bool CloseScreenImageModel(void);
// 关机前关闭视频与相关资源
void CloseVideo();
+ // 复杂操作函数(在新线程中执行)
+ static void ComplexOperationThread(bool isNewDialogue);
// 打开遮罩(部分视图需要)
void OpenBackGround(void);
// 刷新黄色背景
//存储表情和发型信息函数
std::string ReadlocalExpression();
std::string ReadlocalHair();
- bool ReadlocalScreenImage();
+ int ReadlocalScreenImage();
// 对话状态相关函数
int GetConversationStatus();
void HandleTaskReminder(const char* scheduleName);
// 角色配置更改处理函数
- void HandleCharacterConfigChange(const char* characterId, const char* characterName,
- const char* eyesShape, const char* hairColor,
- const char* eyesColor, const char* hairStyle,
- int screenImageAsEmoji);
+ void HandleCharacterConfigChange(const char* characterId, const char* characterName,
+ const char* eyesShape, const char* hairColor,
+ const char* eyesColor, const char* hairStyle,
+ int hasScreenImage,
+ int screenImageAsEmoji);
// 聊天体力更改处理函数
void HandleChatStaminaChange(int chatLeft, const char* chatDesc, int flowLeft,
std::string eyesColor_;
std::string hairStyle_;
std::string screenImage_;
+ int hasScreenImage_{0};
bool screenImageAsEmoji_{false};
// 上次角色配置
std::string last_eyesColor_;
std::string last_hairStyle_;
std::string last_screenImage_;
+ int last_hasScreenImage_{0};
bool last_screenImageAsEmoji_{false};
// 对话状态显示相关变量
// 对话模式相关标志
bool m_dialogueModeFinished = false; // 对话模式是否已finished(收到finished=true)
+
+ // 屏保关闭标志(用于记录在进入对话/哄睡时是否关闭了屏保)
+ bool m_screenImageClosedForDialogue = false; // 进入对话模式时是否关闭了屏保
+ bool m_screenImageClosedForLullaby = false; // 进入哄睡模式时是否关闭了屏保
};
}
#include "battery_hal.h"
#include "battery_service.h"
#include "custom_runtime.h"
+#include "cmsis_os2.h"
+#include "thread_init.h"
+#include "soc_osal.h"
#include <service/graphic_service.h>
#include "ln_api.h"
#include "common/screen.h"
{
static constexpr int16_t VIDEO_WIDTH = 360;
static constexpr int16_t VIDEO_HEIGHT = 360;
+
+ // 复杂操作线程配置和消息队列
+ static app_task_definition_t g_complex_operation_taskcfg = {0};
+ static unsigned long g_complex_operation_queue = 0xFFFFFFFF;
+
+ // 消息结构体
+ typedef struct {
+ bool isNewDialogue;
+ } ComplexOperationMsg_t;
+
+ // 创建消息队列
+ static void create_complex_operation_queue(void)
+ {
+ if (osal_msg_queue_create("complex_operation_queue", 32, &g_complex_operation_queue,
+ 0, sizeof(ComplexOperationMsg_t)) != ERRCODE_SUCC)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "create_complex_operation_queue: Failed to create queue");
+ }
+ else
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "create_complex_operation_queue: Queue created successfully");
+ }
+ }
+
+ // 复杂操作线程函数(在线程中循环等待消息并执行)
+ static void complex_operation_task(void *arg)
+ {
+ (void)arg;
+ errcode_t ret;
+ ComplexOperationMsg_t msg = {0};
+ uint32_t msgsize = sizeof(ComplexOperationMsg_t);
+
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "complex_operation_task: Thread started, waiting for messages");
+
+ while (1)
+ {
+ // 每轮重置 msgsize,兼容底层可能改写该值的实现
+ msgsize = sizeof(ComplexOperationMsg_t);
+ ret = osal_msg_queue_read_copy(g_complex_operation_queue, (void *)&msg, &msgsize,
+ OSAL_MSGQ_WAIT_FOREVER);
+ if (ret != OSAL_SUCCESS)
+ {
+ WEARABLE_LOGW(WEARABLE_LOG_MODULE_APP, "complex_operation_task: Failed to read queue, ret=%d", ret);
+ LOS_Msleep(100);
+ continue;
+ }
+
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "complex_operation_task: Received message, isNewDialogue=%d", msg.isNewDialogue);
+
+ // 在线程中执行复杂操作
+ if(msg.isNewDialogue)
+ {
+ AI_ForceInterrupt();
+ ln_ws_end_audio_chat();
+ ln_ws_send_voice_chat_interrupt("新对话开始");
+ }
+ else
+ {
+ AI_ForceInterrupt();
+ ln_ws_end_audio_chat();
+ ln_ws_send_voice_chat_interrupt("退出对话");
+ }
+ }
+ }
+
+ // 复杂操作函数(向消息队列发送消息,在线程中执行)
+ void ThunderBirdMainView::ComplexOperationThread(bool isNewDialogue)
+ {
+ if (g_complex_operation_queue == 0xFFFFFFFF)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ComplexOperationThread: Message queue not initialized");
+ return;
+ }
+
+ ComplexOperationMsg_t send_data = {0};
+ send_data.isNewDialogue = isNewDialogue;
+
+ // 向消息队列发送消息
+ errcode_t ret = osal_msg_queue_write_copy(g_complex_operation_queue, (void *)&send_data,
+ sizeof(ComplexOperationMsg_t), 0);
+ if (ret != ERRCODE_SUCC)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ComplexOperationThread: Failed to send message to queue, ret=%d", ret);
+ }
+ else
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ComplexOperationThread: Message sent to queue, isNewDialogue=%d", isNewDialogue);
+ }
+ }
static constexpr int16_t STRIDE_ALIGNMENT_VALUE = 128;
static constexpr int16_t JPEG_WIDTH_BYTE_ALIGNMENT = 128;
static constexpr int16_t JPEG_HEIGHT_BYTE_ALIGNMENT = 16;
}
void ThunderBirdMainView::OnStart()//开机操作
{
+ // 创建复杂操作线程(栈大小0x1000 = 4096字节)
+ if (g_complex_operation_taskcfg.task_handle == nullptr)
+ {
+ g_complex_operation_taskcfg.create_queue_handle = create_complex_operation_queue;
+ g_complex_operation_taskcfg.attr.name = "complex_operation_task";
+ g_complex_operation_taskcfg.attr.priority = osPriorityNormal;
+ g_complex_operation_taskcfg.attr.stack_size = 0x1000; // 4096字节
+ g_complex_operation_taskcfg.func = complex_operation_task;
+ g_complex_operation_taskcfg.use_mem = USE_EXTEND_MEM;
+
+ errcode_t ret = uapi_create_osThread_custom(&g_complex_operation_taskcfg);
+ if (ret != ERRCODE_SUCC)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdMainView::OnStart: Failed to create complex operation thread, ret=%d", ret);
+ }
+ else
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ThunderBirdMainView::OnStart: Complex operation thread created successfully");
+ }
+ }
//下载文件被打断的恢复操作
if(ThunderBirdModel::GetInstance()->GetDownloadFile() != -1)
//backGroundView->SetVisible(false);
ScrollView_->Add(backGroundView);
- if(ThunderBirdModel::GetInstance()->ReadlocalScreenImage() == true)//开启屏保模式
+ int screenImageMode = ThunderBirdModel::GetInstance()->ReadlocalScreenImage();
+ if(screenImageMode == 1 || screenImageMode == 2)//开启屏保模式(1:屏保模式,2:屏保模式作为对话表情)
{
printf("开启屏保模式\n");
OpenScreenImageModel();
last_hairColor_ = hairColor_;
last_eyesColor_ = eyesColor_;
last_hairStyle_ = hairStyle_;
+ last_hasScreenImage_ = hasScreenImage_;
last_screenImageAsEmoji_ = screenImageAsEmoji_;
printf(" eyesShape_ = %s", eyesShape_.c_str());
printf(" hairColor_ = %s", hairColor_.c_str());
printf(" eyesColor_ = %s", eyesColor_.c_str());
printf(" hairStyle_ = %s", hairStyle_.c_str());
+ printf(" hasScreenImage_ = %d", hasScreenImage_);
printf(" screenImageAsEmoji_ = %d", screenImageAsEmoji_);
// 初始化对话状态显示变量
{
if (init_falg == false)
{
- //发送获取绑定用户ID,异步执行,避免阻塞UI线程
- GraphicService::GetInstance()->PostGraphicEvent([]() {
+ //发送获取绑定用户ID
do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_GET_USER_ID, NULL, 0);
- });
cat1_gettime();
if( ThunderBirdGuideView::GetInstance() != nullptr)
{
else if (currentView == THUNDERBIRD_REMINDERVIEW &&
currentSubView == ThunderBirdReminderView::THUNDERBIRD_REMINDERVIEW_TASK_REMINDER) {
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "任务提醒界面超时,返回原任务");
- //设置提醒音量为0
- GraphicService::GetInstance()->PostGraphicEvent([]() {
+
ln_schedule_reminder_set_volume_zero();
- });
+
ThunderBirdModel::GetInstance()->HighFrequence();
ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW, ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_STATUS_SHOW);
//关闭语音初始化
void ThunderBirdModel::HandleCharacterConfigChange(const char* characterId, const char* characterName,
const char* eyesShape, const char* hairColor,
const char* eyesColor, const char* hairStyle,
+ int hasScreenImage,
int screenImageAsEmoji)
{
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleCharacterConfigChange");
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " hairColor: %s", hairColor ? hairColor : "null");
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " eyesColor: %s", eyesColor ? eyesColor : "null");
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " hairStyle: %s", hairStyle ? hairStyle : "null");
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " hasScreenImage: %d", hasScreenImage);
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " screenImageAsEmoji: %d", screenImageAsEmoji);
// 将传入的参数转换为std::string(处理nullptr和字符串比较)
// 比较传入的新值和上次保存的值(last_xxx_)
if(newEyesShape == last_eyesShape_ && newHairColor == last_hairColor_ &&
newEyesColor == last_eyesColor_ && newHairStyle == last_hairStyle_ &&
- screenImageAsEmoji == last_screenImageAsEmoji_)
+ hasScreenImage == last_hasScreenImage_ && screenImageAsEmoji == last_screenImageAsEmoji_)
{
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleCharacterConfigChange: 角色配置没有变化,不进行处理");
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " 上次配置: eyesShape=%s, hairColor=%s, eyesColor=%s, hairStyle=%s, screenImageAsEmoji=%d",
// 检查是否是默认/空配置(calm-eyes, amber, warm-orange, curly-hair)
if(newEyesShape == "calm-eyes" && newEyesColor == "amber" &&
newHairColor == "orange" && newHairStyle == "curly-hair" && screenImageAsEmoji == false &&
- last_eyesShape_.empty() && last_hairColor_.empty() && last_eyesColor_.empty() && last_hairStyle_.empty() && last_screenImageAsEmoji_ == false)
+ last_eyesShape_.empty() && last_hairColor_.empty() && last_eyesColor_.empty() && last_hairStyle_.empty() && last_hasScreenImage_ == false && last_screenImageAsEmoji_ == false)
{
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleCharacterConfigChange: 角色配置为默认配置,不进行处理");
// 更新last_xxx_为当前值,避免下次误判
eyesColor_ = newEyesColor;
hairStyle_ = newHairStyle;
screenImageAsEmoji_ = screenImageAsEmoji;
-
+ hasScreenImage_ = hasScreenImage;
//更新上次角色配置信息(在处理完成后更新,用于下次比较)
last_eyesShape_ = newEyesShape;
last_hairColor_ = newHairColor;
last_eyesColor_ = newEyesColor;
last_hairStyle_ = newHairStyle;
last_screenImageAsEmoji_ = screenImageAsEmoji;
-
+ last_hasScreenImage_ = hasScreenImage;
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleCharacterConfigChange: 角色配置已更新");
// SaveCharacterConfig(characterId, characterName, eyesShape, hairColor, eyesColor, hairStyle, screenImageAsEmoji);
return "/user/res/hair/" + hairStyle_ + "/" + hairColor_ + ".bin";
}
//是否开启屏保模式
- bool ThunderBirdModel::ReadlocalScreenImage()
+ int ThunderBirdModel::ReadlocalScreenImage()
{
- return screenImageAsEmoji_;
+ //0:关闭屏保模式 1:开启屏保模式 2:屏保模式作为对话表情
+ if(hasScreenImage_ == 0)
+ {
+ return 0;
+ }
+ else if(screenImageAsEmoji_ == true)
+ {
+ return 2;
+ }
+ return 1;
}
void ThunderBirdModel::HandleChatStaminaChange(int chatLeft, const char* chatDesc, int flowLeft,
// 设置标志位,表示在对话模式中
m_needGetTimelineExpression = true;
+ // 如果ReadlocalScreenImage() == 1(有屏保但不是作为对话表情),先关闭屏保
+ int screenImageMode = ReadlocalScreenImage();
+ if (screenImageMode == 1) {
+ // 有屏保但不是作为对话表情,需要先关闭屏保
+ ThunderBirdMainView* mainView = ThunderBirdMainView::GetInstance();
+ if (mainView != nullptr && mainView->GetIsOpenScreenImageModel()) {
+ mainView->CloseScreenImageModel();
+ m_screenImageClosedForDialogue = true;
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnEnterDialogueMode: 关闭屏保模式(ReadlocalScreenImage==1)");
+ }
+ } else {
+ m_screenImageClosedForDialogue = false;
+ }
+
// 等待视频切换完成,避免在视频切换过程中切换表情导致冲突
if (ThunderBirdMainView::GetInstance() && ThunderBirdMainView::IsSwitchingVideo()) {
WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnEnterDialogueMode: 等待视频切换完成");
ln_bt_earphone_set_volume(m_volume);
}
- // 切换到眨眼表情(winking)
- std::string winkingExpressionPath = "/user/res/video/CloseEyes/" + eyesShape_ + "/" + eyesColor_ + ".mp4";
-
- // 检查文件是否存在
- if (access(winkingExpressionPath.c_str(), F_OK) == 0) {
- // 切换到眨眼表情(但不更新m_currentExpression,因为退出时要恢复时间线表情)
- SwitchExpressionVideo(winkingExpressionPath.c_str());
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnEnterDialogueMode: 切换到眨眼表情: %s", winkingExpressionPath.c_str());
+ // 如果ReadlocalScreenImage() == 2(屏保作为对话表情),播放屏保图片
+ if (screenImageMode == 2) {
+ // 屏保作为对话表情,播放屏保图片
+ ThunderBirdMainView* mainView = ThunderBirdMainView::GetInstance();
+ if (mainView != nullptr && access(LN_DEVICE_SCREEN_IMAGE_FILE, F_OK) == 0) {
+ // 暂停视频播放(如果正在播放)
+ if (mainView->videoPlay_ != nullptr &&
+ mainView->videoPlay_->isEntered_ && mainView->videoPlay_->isPlayed_) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnEnterDialogueMode: 暂停视频播放以显示屏保图片");
+ mainView->videoPlay_->PauseVideoPlay();
+ }
+ // 屏保图片存在,切换到屏保图片
+ mainView->SwitchIconImage(LN_DEVICE_SCREEN_IMAGE_FILE);
+ // 设置iconView为可见状态
+ if (mainView->iconView != nullptr) {
+ mainView->iconView->SetVisible(true);
+ }
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnEnterDialogueMode: screenImageMode==2,切换到屏保图片: %s", LN_DEVICE_SCREEN_IMAGE_FILE);
+ } else {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnEnterDialogueMode: screenImageMode==2,但屏保图片文件不存在: %s", LN_DEVICE_SCREEN_IMAGE_FILE);
+ }
} else {
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnEnterDialogueMode: 眨眼表情文件不存在: %s", winkingExpressionPath.c_str());
+ // 正常情况,切换到眨眼表情(winking)
+ std::string winkingExpressionPath = "/user/res/video/CloseEyes/" + eyesShape_ + "/" + eyesColor_ + ".mp4";
+
+ // 检查文件是否存在
+ if (access(winkingExpressionPath.c_str(), F_OK) == 0) {
+ // 切换到眨眼表情(但不更新m_currentExpression,因为退出时要恢复时间线表情)
+ SwitchExpressionVideo(winkingExpressionPath.c_str());
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnEnterDialogueMode: 切换到眨眼表情: %s", winkingExpressionPath.c_str());
+ } else {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnEnterDialogueMode: 眨眼表情文件不存在: %s", winkingExpressionPath.c_str());
+ }
}
}
// 重置对话模式finished标志
m_dialogueModeFinished = false;
+ // 如果之前在进入对话时关闭了屏保,现在需要恢复屏保
+ if (m_screenImageClosedForDialogue) {
+ int screenImageMode = ReadlocalScreenImage();
+ if (screenImageMode == 1) {
+ // 有屏保但不是作为对话表情,恢复屏保
+ if (mainView != nullptr && !mainView->GetIsOpenScreenImageModel()) {
+ mainView->OpenScreenImageModel();
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnExitDialogueMode: 恢复屏保模式(ReadlocalScreenImage==1)");
+ }
+ }
+ m_screenImageClosedForDialogue = false;
+ }
+
// 不在这里切换表情,标志位保持为1,在发呆中界面时获取时间线表情
// m_needGetTimelineExpression 保持为 true,表示需要获取时间线表情
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnExitDialogueMode: 退出对话模式,标志位保持为true,将在发呆中界面获取时间线表情");
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnEnterLullabyMode: 记录时间线表情: %s", m_currentExpression.c_str());
// 设置标志位,表示在哄睡模式中
m_needGetTimelineExpression = true;
+
+ // 如果ReadlocalScreenImage() == 1(有屏保但不是作为对话表情),先关闭屏保
+ int screenImageMode = ReadlocalScreenImage();
+ if (screenImageMode == 1) {
+ // 有屏保但不是作为对话表情,需要先关闭屏保
+ ThunderBirdMainView* mainView = ThunderBirdMainView::GetInstance();
+ if (mainView != nullptr && mainView->GetIsOpenScreenImageModel()) {
+ mainView->CloseScreenImageModel();
+ m_screenImageClosedForLullaby = true;
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnEnterLullabyMode: 关闭屏保模式(ReadlocalScreenImage==1)");
+ }
+ } else {
+ m_screenImageClosedForLullaby = false;
+ }
+
//如果本来就是眨眼的表情直接返回
if (m_currentExpression == "winking" || m_currentExpression.empty() == true) {
return;
void ThunderBirdModel::OnExitLullabyMode()
{
// 隐藏小绿点
- if (ThunderBirdMainView::GetInstance() && ThunderBirdMainView::GetInstance()->listenIcon) {
- ThunderBirdMainView::GetInstance()->listenIcon->SetVisible(false);
+ ThunderBirdMainView* mainView = ThunderBirdMainView::GetInstance();
+ if (mainView != nullptr && mainView->listenIcon) {
+ mainView->listenIcon->SetVisible(false);
+ }
+
+ // 如果之前在进入哄睡时关闭了屏保,现在需要恢复屏保
+ if (m_screenImageClosedForLullaby) {
+ int screenImageMode = ReadlocalScreenImage();
+ if (screenImageMode == 1) {
+ // 有屏保但不是作为对话表情,恢复屏保
+ if (mainView != nullptr && !mainView->GetIsOpenScreenImageModel()) {
+ mainView->OpenScreenImageModel();
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnExitLullabyMode: 恢复屏保模式(ReadlocalScreenImage==1)");
+ }
+ }
+ m_screenImageClosedForLullaby = false;
}
// 不在这里切换表情,标志位保持为1,在发呆中界面时获取时间线表情
ThunderBirdDialogueView::GetInstance()->UpdateDialogueText(m_currentStatusText.c_str());
//切换表情
- //不为屏保模式
+ //不为屏保模式(ReadlocalScreenImage() == 1 时,在发呆中界面也应该显示屏保,不切换表情)
std::string expressionPath;
std::string targetExpression = expression;
+ int screenImageMode = ReadlocalScreenImage();
+ // 如果ReadlocalScreenImage() == 1(有屏保但不是作为对话表情),在发呆中界面不切换表情,保持屏保显示
+ if(screenImageMode == 1 && currentView == THUNDERBIRD_DIALOGUEVIEW && currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_STATUS_SHOW)
+ {
+ // 有屏保但不是作为对话表情,在发呆中界面保持屏保显示,不切换表情
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::SetCurrentExpressionAndStatus: ReadlocalScreenImage()==1,在发呆中界面保持屏保显示,不切换表情");
+ return;
+ }
if(screenImageAsEmoji_ == false)
{
//获取当前角色配置
* @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/ThunderBird/src/ThunderBirdPresenter.cpp
*/
#include "thunderbird/include/ThunderBirdPresenter.h"
+#include "thunderbird/include/ThunderBirdMainView.h"
#include "thunderbird/include/ThunderBirdGuideView.h"
#include "thunderbird/include/ThunderBirdLullabyView.h"
#include "thunderbird/include/ThunderBirdDialogueView.h"
// WebSocket 未连接,不执行操作,避免状态混乱
return;
}
- AI_ForceInterrupt();
- ln_ws_end_audio_chat();
- ln_ws_send_voice_chat_interrupt("新对话开始");
+ ThunderBirdMainView::ComplexOperationThread(true);
ThunderBirdDialogueView::GetInstance()->IsReconnect = true;
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始录音,跳转到聆听状态");
// 开始录音
{
//回原界面
ThunderBirdModel::GetInstance()->StopCountUpTimer(); // 手动跳转时关闭定时器
- //设置提醒音量为0(异步执行,避免阻塞按键处理,特别是在连网状态下)
- GraphicService::GetInstance()->PostGraphicEvent([]() {
+
ln_schedule_reminder_set_volume_zero();
- });
+
ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW, ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_STATUS_SHOW);
//关闭语音初始化
// AI_ForceInterrupt();
if (async) {
// 异步执行,避免阻塞按键处理
- GraphicService::GetInstance()->PostGraphicEvent([volumeToApply]() {
+
AudioManager::GetInstance().SetVolume(AUDIO_STREAM_VOICE_ASSISTANT, volumeToApply);
ln_bt_earphone_set_volume(volumeToApply);
// 更新Model中的音量值
ThunderBirdModel::GetInstance()->m_volume = volumeToApply;
- });
} else {
// 同步执行
AudioManager::GetInstance().SetVolume(AUDIO_STREAM_VOICE_ASSISTANT, volumeToApply);
fields.push_back(field);
}
- if (fields.size() < 7) {
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandTaskCharacterConfigNotify: invalid payload format, expected 7 fields, got %zu", fields.size());
+ if (fields.size() < 8) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandTaskCharacterConfigNotify: invalid payload format, expected 8 fields, got %zu", fields.size());
return;
}
std::string hairColor = fields[3];
std::string eyesColor = fields[4];
std::string hairStyle = fields[5];
- int screenImageAsEmoji = std::stoi(fields[6]);
+ int hasScreenImage = std::stoi(fields[6]);
+ int screenImageAsEmoji = std::stoi(fields[7]);
WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandTaskCharacterConfigNotify characterId = %s", characterId.c_str());
WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandTaskCharacterConfigNotify characterName = %s", characterName.c_str());
WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandTaskCharacterConfigNotify hairColor = %s", hairColor.c_str());
WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandTaskCharacterConfigNotify eyesColor = %s", eyesColor.c_str());
WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandTaskCharacterConfigNotify hairStyle = %s", hairStyle.c_str());
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandTaskCharacterConfigNotify hasScreenImage = %d", hasScreenImage);
WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandTaskCharacterConfigNotify screenImageAsEmoji = %d", screenImageAsEmoji);
// 通过图形服务调用 ThunderBirdModel 的处理函数
GraphicService::GetInstance()->PostGraphicEvent(
- [characterId, characterName, eyesShape, hairColor, eyesColor, hairStyle, screenImageAsEmoji]() {
+ [characterId, characterName, eyesShape, hairColor, eyesColor, hairStyle, hasScreenImage, screenImageAsEmoji]() {
if (OHOS::ThunderBirdModel::GetInstance()) {
OHOS::ThunderBirdModel::GetInstance()->HandleCharacterConfigChange(
characterId.c_str(), characterName.c_str(), eyesShape.c_str(),
- hairColor.c_str(), eyesColor.c_str(), hairStyle.c_str(), screenImageAsEmoji);
+ hairColor.c_str(), eyesColor.c_str(), hairStyle.c_str(), hasScreenImage, screenImageAsEmoji);
}
});
}
WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " avatar_screen_image_as_emoji: %d\n", g_ln_character_config.avatar_screen_image_as_emoji);
// 如果屏保图片不为空,则保存到本地
- if (g_ln_character_config.avatar_screen_image && strlen(g_ln_character_config.avatar_screen_image) > 0 && g_ln_character_config.avatar_screen_image_as_emoji == 1)
+ // 条件1:screenImageAsEmoji为真时,下载屏保(作为对话表情)
+ // 条件2:deviceScreen不为空时,下载屏保(屏保模式)
+ int need_download_screen_image = 0;
+ if (g_ln_character_config.avatar_screen_image && strlen(g_ln_character_config.avatar_screen_image) > 0)
+ {
+ if (g_ln_character_config.avatar_screen_image_as_emoji == 1)
+ {
+ // screenImageAsEmoji为真,屏保作为对话表情
+ need_download_screen_image = 1;
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DEVICE_CHARACTER] 屏保图片不为空且screenImageAsEmoji为真,下载屏保图片(作为对话表情)");
+ }
+ else
+ {
+ // deviceScreen不为空,屏保模式
+ need_download_screen_image = 1;
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DEVICE_CHARACTER] 屏保图片不为空,下载屏保图片(屏保模式)");
+ }
+ }
+
+ if (need_download_screen_image)
{
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DEVICE_CHARACTER] 屏保图片不为空,下载屏保图片");
/* 解析阶段先拷贝URL,避免稍后清理结构体后URL丢失 */
ln_set_pending_screen_image(g_ln_character_config.avatar_screen_image);
if(uapi_ln_get_file_download_type() == LN_FILE_DOWNLOAD_TYPE_NONE && uapi_ln_is_file_downloading() == 0)
g_ln_character_config.avatar_hair_color,
g_ln_character_config.avatar_eyes_color,
g_ln_character_config.avatar_hair_style,
+ need_download_screen_image,
g_ln_character_config.avatar_screen_image_as_emoji);
cJSON_Delete(root);
printf(" avatar_screen_image_as_emoji: %d\n", g_ln_character_config.avatar_screen_image_as_emoji);
// 如果屏保图片不为空,则保存到本地
- if (g_ln_character_config.avatar_screen_image && strlen(g_ln_character_config.avatar_screen_image) > 0 && g_ln_character_config.avatar_screen_image_as_emoji == 1)
+ if (g_ln_character_config.avatar_screen_image && strlen(g_ln_character_config.avatar_screen_image) > 0)
{
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DEVICE_CHARACTER] 屏保图片不为空,下载屏保图片");
/* 解析阶段先拷贝URL,避免稍后清理结构体后URL丢失 */
}
/* 推送角色配置更改通知 */
+ // 判断是否有屏保:avatar_screen_image不为空
+ int has_screen_image = (g_ln_character_config.avatar_screen_image && strlen(g_ln_character_config.avatar_screen_image) > 0) ? 1 : 0;
push_character_config_change_notification(g_ln_character_config.character_id,
g_ln_character_config.character_name,
g_ln_character_config.avatar_eyes_shape,
g_ln_character_config.avatar_hair_color,
g_ln_character_config.avatar_eyes_color,
g_ln_character_config.avatar_hair_style,
+ has_screen_image,
g_ln_character_config.avatar_screen_image_as_emoji);
cJSON_Delete(root);
const char *hairColor,
const char *eyesColor,
const char *hairStyle,
+ int hasScreenImage,
int screenImageAsEmoji)
{
// 组装紧凑 payload: 使用分隔符拼装,UI 侧再拆分(或改用结构体)
const char *hc = hairColor ? hairColor : "";
const char *ec = eyesColor ? eyesColor : "";
const char *hs = hairStyle ? hairStyle : "";
- (void)snprintf(payload, sizeof(payload) - 1, "%s|%s|%s|%s|%s|%s|%d", id,n, es, hc, ec, hs, screenImageAsEmoji ? 1 : 0);
- printf("push_character_config_change_notification: characterId=%s, characterName=%s, eyesShape=%s, hairColor=%s, eyesColor=%s, hairStyle=%s, screenImageAsEmoji=%d\r\n", id, n, es, hc, ec, hs, screenImageAsEmoji ? 1 : 0);
+ (void)snprintf(payload, sizeof(payload) - 1, "%s|%s|%s|%s|%s|%s|%d|%d", id,n, es, hc, ec, hs, hasScreenImage ? 1 : 0, screenImageAsEmoji ? 1 : 0);
+ printf("push_character_config_change_notification: characterId=%s, characterName=%s, eyesShape=%s, hairColor=%s, eyesColor=%s, hairStyle=%s, hasScreenImage=%d, screenImageAsEmoji=%d\r\n", id, n, es, hc, ec, hs, hasScreenImage ? 1 : 0, screenImageAsEmoji ? 1 : 0);
SendMsgToUIService(HAND_CHARACTER_CONFIG_CHANGE_NOTIFY, 0, (void *)payload, (int32_t)strlen(payload));
}
const char *hairColor,
const char *eyesColor,
const char *hairStyle,
+ int hasScreenImage,
int screenImageAsEmoji);
//通知ui跳转哄睡界面,是否是意图识别结果
void push_sleep_mode_start_notification(const char *storyTheme, int is_intention_result);