From d0885634ebb91ff02a20fae083bd13a54ec1fd9b Mon Sep 17 00:00:00 2001 From: xue <2144439972@qq.com> Date: Fri, 26 Sep 2025 15:15:44 +0800 Subject: [PATCH] =?utf8?q?=E5=A2=9E=E5=8A=A0=E8=A7=92=E8=89=B2=E9=85=8D?= =?utf8?q?=E7=BD=AE=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../nativeui/uiservice/src/ui_service.cpp | 60 +++++++++++++++++- .../zhihui/leiniao/imsl_ln/leiniao_api_at.c | 62 +++++++++++++++++++ .../leiniao/imsl_ln/ln_api_device_info.c | 2 +- .../leiniao/ln_api_cpp/ln_api_interface.cpp | 21 +++++++ .../leiniao/ln_api_cpp/ln_api_interface.h | 3 + 5 files changed, 145 insertions(+), 3 deletions(-) diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/uiservice/src/ui_service.cpp b/code/sdk/application/wearable/ln/nativeapp/nativeui/uiservice/src/ui_service.cpp index db5c6f1ea..bd0bdacd7 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/uiservice/src/ui_service.cpp +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/uiservice/src/ui_service.cpp @@ -21,6 +21,8 @@ #include "ohos_init.h" #include "memory_adapter.h" #include +#include +#include #include "service_id_define.h" #include "bundle_install_msg.h" #include "graphic_service.h" @@ -371,8 +373,56 @@ void HandTaskReminderNotify(Request *request) } void HandTaskCharacterConfigNotify(Request *request) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandTaskCharacterConfigNotify msg_id = %d",request->msgId); - int status = *(int *)request->data; + WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandTaskCharacterConfigNotify msg_id = %d", request->msgId); + + if (request->data == nullptr || request->len <= 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandTaskCharacterConfigNotify: invalid data"); + return; + } + + // 解析接收到的数据:角色配置信息(以'|'分隔) + // 格式: "characterId|characterName|eyesShape|hairColor|eyesColor|hairStyle|screenImageAsEmoji" + std::string payload(static_cast(request->data), request->len); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandTaskCharacterConfigNotify payload = %s", payload.c_str()); + + // 解析各个字段 + std::vector fields; + std::stringstream ss(payload); + std::string field; + while (std::getline(ss, field, '|')) { + 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()); + return; + } + + std::string characterId = fields[0]; + std::string characterName = fields[1]; + std::string eyesShape = fields[2]; + std::string hairColor = fields[3]; + std::string eyesColor = fields[4]; + std::string hairStyle = fields[5]; + int screenImageAsEmoji = std::stoi(fields[6]); + + 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 eyesShape = %s", eyesShape.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 screenImageAsEmoji = %d", screenImageAsEmoji); + + // 通过图形服务调用 ThunderBirdModel 的处理函数 + GraphicService::GetInstance()->PostGraphicEvent( + [characterId, characterName, eyesShape, hairColor, eyesColor, hairStyle, 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); + } + }); } // 哄睡模式开始通知 @@ -381,11 +431,17 @@ void HandSleepModeStartNotify(Request *request) WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandSleepModeStartNotify msg_id = %d", request->msgId); std::string theme(static_cast(request->data), request->len); WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandSleepModeStartNotify storyTheme = %s", theme.c_str()); + //跳转到哄睡模式 + GraphicService::GetInstance()->PostGraphicEvent( + std::bind(&OHOS::ThunderBirdModel::HandleSleepModeStart,OHOS::ThunderBirdModel::GetInstance(),theme.c_str())); } // 哄睡模式结束通知 void HandSleepModeEndNotify(Request *request) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandSleepModeEndNotify msg_id = %d",request->msgId); + GraphicService::GetInstance()->PostGraphicEvent( + std::bind(&OHOS::ThunderBirdModel::HandleSleepModeEnd,OHOS::ThunderBirdModel::GetInstance())); + } // 下载表情通知 diff --git a/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c b/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c index 1a5e3d0db..6a11da4e3 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c @@ -50,6 +50,9 @@ static uint32_t ln_factory_at(uint8_t *para, uint32_t paraLen, char *strCommonCm static uint32_t ln_memory_info_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd); static uint32_t ln_folder_size_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd); +//表情切换相关AT命令函数声明 +static uint32_t ln_switch_expression_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd); + //帧率控制相关AT命令函数声明 static uint32_t ln_set_fps_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd); static uint32_t ln_get_fps_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd); @@ -1596,6 +1599,64 @@ static uint32_t ln_chat_stamina_demo_at(uint8_t *para, uint32_t paraLen, char *s printf("[LN][CHAT_STAMINA_DEMO] chatLeft=%d, flowLeft=%d\n", chatLeft, flowLeft); return ERRCODE_SUCC; } +/** + * @brief AT^LN_SWITCH_EXPRESSION= - 切换表情视频 + * @param para 参数字符串(视频文件路径) + * @param paraLen 参数长度 + * @param strCommonCmd 命令字符串(未使用) + * @return uint32_t 错误码 + * + * 功能:切换表情视频 + * 用法:AT^LN_SWITCH_EXPRESSION=/user/res/video/Angry.mp4 + * AT^LN_SWITCH_EXPRESSION=/user/res/video/Happy.mp4 + */ +static uint32_t ln_switch_expression_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + VAD_UNUSED(strCommonCmd); + + uint8_t argv[LN_MAX_ARGC][LN_MAX_ARGV_LEN] = {0}; + uint32_t argc = 0; + + // 解析参数 + if (ConvertCmdToParam(para, paraLen, argv, &argc) != VAD_SUCCESS) { + printf("ERROR: Failed to parse parameters\n"); + return ERRCODE_FAIL; + } + + if (argc < 1) { + printf("ERROR: Missing video path parameter\n"); + printf("Usage: AT^LN_SWITCH_EXPRESSION=\n"); + printf("Example: AT^LN_SWITCH_EXPRESSION=/user/res/video/Angry.mp4\n"); + return ERRCODE_FAIL; + } + + const char *video_path = (char*)argv[0]; + if (video_path == NULL || strlen(video_path) == 0) { + printf("ERROR: Empty video path parameter\n"); + return ERRCODE_FAIL; + } + + // 检查路径长度限制 + if (strlen(video_path) > 256) { + printf("ERROR: Video path too long (max 256 characters)\n"); + return ERRCODE_FAIL; + } + + printf("[LN][SWITCH_EXPRESSION] Switching to video: %s\n", video_path); + + // 调用C接口切换表情视频 + bool result = switch_expression_video(video_path); + + if (result) { + printf("+LN_SWITCH_EXPRESSION: OK\n"); + printf("Expression video switched successfully: %s\n", video_path); + return ERRCODE_SUCC; + } else { + printf("+LN_SWITCH_EXPRESSION: FAIL\n"); + printf("Failed to switch expression video: %s\n", video_path); + return ERRCODE_FAIL; + } +} static const at_cmd_table_t g_ln_api_cmd[] = { /* ----------------------------------- VAD ---------------------------------- */ @@ -1656,6 +1717,7 @@ static const at_cmd_table_t g_ln_api_cmd[] = { {(char *)"AT^LN_SLEEP_MODE_END", ln_sleep_mode_end_at, (char *)"哄睡模式结束: AT^LN_SLEEP_MODE_END"}, {(char *)"AT^LN_DOWNLOAD_EMOJI", ln_download_emoji_at, (char *)"下载表情: AT^LN_DOWNLOAD_EMOJI[=characterId,eyesColor,eyesShape]"}, {(char *)"AT^LN_CHAT_STAMINA_DEMO", ln_chat_stamina_demo_at, (char *)"演示对话体力/流量UI: AT^LN_CHAT_STAMINA_DEMO=member|enough|low|empty 或自定义"}, + {(char *)"AT^LN_SWITCH_EXPRESSION", ln_switch_expression_at, (char *)"切换表情视频: AT^LN_SWITCH_EXPRESSION="}, /* 内存查看相关AT命令 */ {(char *)"AT^LN_MEMORY_INFO", ln_memory_info_at, (char *)"查看系统内存信息: AT^LN_MEMORY_INFO"}, {(char *)"AT^LN_FOLDER_SIZE", ln_folder_size_at, (char *)"查看文件夹大小: AT^LN_FOLDER_SIZE[=/path/to/folder]"}, diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_device_info.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_device_info.c index a75892f83..cea8b2ab9 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_device_info.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_device_info.c @@ -228,10 +228,10 @@ void ln_parse_character_config(const char *json_buf, int json_len) /* 推送角色配置更改通知 */ 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, - g_ln_character_config.avatar_eyes_shape, g_ln_character_config.avatar_screen_image_as_emoji); cJSON_Delete(root); diff --git a/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.cpp b/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.cpp index cea9e99d7..d5c1b45f4 100644 --- a/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.cpp +++ b/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.cpp @@ -135,6 +135,7 @@ void push_character_config_change_notification(const char* characterId, 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); SendMsgToUIService(HAND_CHARACTER_CONFIG_CHANGE_NOTIFY, 0, (void *)payload, (int32_t)strlen(payload)); } @@ -178,6 +179,26 @@ void push_chat_stamina_notification(int chatLeft, const char *chatDesc, (void)snprintf(payload, sizeof(payload) - 1, "%d|%s|%d|%s|%s", chatLeft, cd, flowLeft, fd, qr); SendMsgToUIService(HAND_CHAT_STAMINA_NOTIFY, 0, (void *)payload, (int32_t)strlen(payload)); } +// 切换表情视频 +bool switch_expression_video(const char *video_path) +{ + if (video_path == nullptr) { + printf("[LN][SWITCH_VIDEO] Error: video_path is null\n"); + return false; + } + + OHOS::ThunderBirdModel* mainView = OHOS::ThunderBirdModel::GetInstance(); + if (mainView == nullptr) { + printf("[LN][SWITCH_VIDEO] Error: ThunderBirdModel instance is null\n"); + return false; + } + + bool result = mainView->SwitchExpressionVideo(video_path); + printf("[LN][SWITCH_VIDEO] Switching to video: %s, result: %s\n", + video_path, result ? "success" : "failed"); + + return result; +} #ifdef __cplusplus }; #endif \ No newline at end of file diff --git a/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.h b/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.h index 2a67ffd9d..667f446d3 100644 --- a/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.h +++ b/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.h @@ -77,6 +77,9 @@ void push_chat_stamina_notification(int chatLeft, int flowLeft, const char *flowDesc, const char *qrcodeUrl); +// 切换表情视频 +bool switch_expression_video(const char *video_path); + #ifdef __cplusplus } #endif -- 2.17.1