添加表情下载相关at测试,待ui验证 2396/1 2396/head
authorluozheng <1732036298@qq.com>
Thu, 25 Sep 2025 08:55:15 +0000 (16:55 +0800)
committerluozheng <1732036298@qq.com>
Thu, 25 Sep 2025 08:55:15 +0000 (16:55 +0800)
code/sdk/application/wearable/ln/nativeapp/nativeui/include/uiservice/ui_service.h
code/sdk/application/wearable/ln/nativeapp/nativeui/uiservice/src/ui_service.cpp
code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c
code/sdk/zhihui/leiniao/imsl_ln/ln_api.c
code/sdk/zhihui/leiniao/imsl_ln/ln_api_emoji.c
code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.cpp
code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.h

index 1001603..19176de 100644 (file)
@@ -56,6 +56,7 @@ typedef enum {
     HAND_CHARACTER_CONFIG_CHANGE_NOTIFY, // 角色配置更改通知
     HAND_SLEEP_MODE_START_NOTIFY, // 哄睡模式开始通知
     HAND_SLEEP_MODE_END_NOTIFY, // 哄睡模式结束通知
+    HAND_DOWNLOAD_EMOJI_NOTIFY, // 下载表情通知
     MAX_NUM_HANDLER, 
 } UiServiceMsgId;
 
index 6e99561..e2d4136 100644 (file)
@@ -90,6 +90,7 @@ static void HandTaskReminderNotify(Request *request);
 static void HandTaskCharacterConfigNotify(Request *request);
 static void HandSleepModeStartNotify(Request *request);
 static void HandSleepModeEndNotify(Request *request);
+static void HandDownloadEmojiNotify(Request *request);
 // 消息处理程序项数组(每个消息类型对应一个处理函数,函数名以 Handle 开头)
 MsgHandlerEntry msgHandlers[] = {
     {HANDLE_JUMP_OTA_VIEW, HandleJumpOtaView},
@@ -98,6 +99,7 @@ MsgHandlerEntry msgHandlers[] = {
     {HAND_CHARACTER_CONFIG_CHANGE_NOTIFY,HandTaskCharacterConfigNotify},
     {HAND_SLEEP_MODE_START_NOTIFY,HandSleepModeStartNotify},
     {HAND_SLEEP_MODE_END_NOTIFY,HandSleepModeEndNotify},
+    {HAND_DOWNLOAD_EMOJI_NOTIFY,HandDownloadEmojiNotify},
 };
 /* -------------------------------------------------------------------------- */
 void ScreenTurnOn(int32_t timeout)
@@ -383,6 +385,19 @@ void HandSleepModeEndNotify(Request *request)
 {
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandSleepModeEndNotify msg_id = %d",request->msgId);
 }
+// 下载表情通知
+void HandDownloadEmojiNotify(Request *request)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandDownloadEmojiNotify msg_id = %d",request->msgId);
+    std::string value(static_cast<char*>(request->data), request->len);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandDownloadEmojiNotify = %s", value.c_str());
+    std::string characterId = value.substr(0, value.find('|'));
+    std::string eyesColor = value.substr(value.find('|') + 1, value.find('|', value.find('|') + 1) - value.find('|') - 1);
+    std::string eyesShape = value.substr(value.find('|', value.find('|') + 1) + 1);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandDownloadEmojiNotify characterId = %s", characterId.c_str());
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandDownloadEmojiNotify eyesColor = %s", eyesColor.c_str());
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandDownloadEmojiNotify eyesShape = %s", eyesShape.c_str());
+}
 /* -------------------------------------------------------------------------- */
 #ifdef __cplusplus
 }
index 9a2f704..682adc2 100644 (file)
@@ -1419,6 +1419,57 @@ static uint32_t ln_get_device_version_at(uint8_t *para, uint32_t paraLen, char *
     printf("deviceVersion: %s\n", deviceVersion);
     return ERRCODE_SUCC;
 }
+/* AT^LN_DOWNLOAD_EMOJI */
+static uint32_t ln_download_emoji_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+    VAD_UNUSED(para);
+    VAD_UNUSED(paraLen);
+    VAD_UNUSED(strCommonCmd);
+    printf("[LN][DOWNLOAD_EMOJI]\n");
+    char *json = (char*)malloc(1024);
+    if (json == NULL) {
+        printf("[LN][DOWNLOAD_EMOJI] OOM\n");
+        return ERRCODE_FAIL;
+    }
+    const char *deviceId = uapi_ln_get_device_id();
+    const char *id = (deviceId && deviceId[0]) ? deviceId : "DEVICE_LOCAL";
+    const char *characterId = "char_001";
+    const char *eyesColor = "blue";
+    const char *eyesShape = "calm-eyes";
+    int n = snprintf(json, 1024,
+        "{\n"
+        "  \"deviceId\": \"%s\",\n"
+        "  \"timestamp\": %u,\n"
+        "  \"messageId\": \"msg_011\",\n"
+        "  \"command\": \"DownloadEmoji\",\n"
+        "  \"data\": {\n"
+        "    \"characterId\": \"%s\",\n"
+        "    \"eyesColor\": \"%s\",\n"
+        "    \"eyesShape\": \"%s\",\n"
+        "    \"emotionEmojis\": [\n"
+        "      {\n"
+        "        \"emotion\": \"happy\",\n"
+        "        \"emojiUrl\": \"https://example.com/emoji/happy.mp4\"\n"
+        "      },\n"
+        "      {\n"
+        "        \"emotion\": \"sad\",\n"
+        "        \"emojiUrl\": \"https://example.com/emoji/sad.mp4\"\n"
+        "      }\n"
+        "    ]\n"
+        "  }\n"
+        "}\n",
+        id, 0U, characterId, eyesColor, eyesShape);
+    if (n <= 0 || n >= 1024) {
+        free(json);
+        printf("[LN][DOWNLOAD_EMOJI] build json failed\n");
+        return ERRCODE_FAIL;
+    }
+    printf("[LN][DOWNLOAD_EMOJI] json = %s\n", json);
+    // ln_parse_download_emoji(json, n);
+    push_download_emoji_notification(characterId, eyesColor, eyesShape);
+    free(json);
+    return ERRCODE_SUCC;
+}
 static const at_cmd_table_t g_ln_api_cmd[] = {
     /* ----------------------------------- VAD ---------------------------------- */
     {(char *)"AT^VAD_INIT", vad_init, (char *)"初始化 VAD"},
@@ -1474,6 +1525,7 @@ static const at_cmd_table_t g_ln_api_cmd[] = {
     {(char *)"AT^LN_CHARACTER_CFG", ln_character_config_change_at, (char *)"角色配置更改: AT^LN_CHARACTER_CFG[=name,eyesShape,hairColor,eyesColor,hairStyle,screenImageAsEmoji]"},
        {(char *)"AT^LN_SLEEP_MODE_START", ln_sleep_mode_start_at, (char *)"哄睡模式开始: AT^LN_SLEEP_MODE_START[=storyTheme]"},
        {(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]"},
     /* 内存查看相关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]"},
index 698f1be..10435ef 100644 (file)
@@ -326,11 +326,13 @@ int uapi_ln_download_file(const char *url, const char *save_path)
     do
     {
         HTTPC_RESULT recv_res = HttpClientRecvResponse(&client, &client_data);
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] recv_res = %d", recv_res);
         if (recv_res == HTTP_SUCCESS || recv_res == HTTP_EAGAIN)
         {
             if (client_data.contentBlockLen > 0)
             {
                 size_t written = fwrite(client_data.responseBuf, 1, client_data.contentBlockLen, fd);
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] written = %zu", written);
                 if (written != client_data.contentBlockLen)
                 {
                     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] write failed, written=%zu, expected=%d",
index 36fa2b7..4277f7a 100644 (file)
@@ -83,17 +83,14 @@ static void ln_gen_emoji_cache_path(const EmojiPackage *pkg, const EmotionEmoji
     // emojiUrl=https://ambybox-emoji.test.leiniao.com/v1/emoji/getEmoji?characterId=1&eyesColor=1&eyesShape=1&emotion=1
     // path=/user/userdata/leiniao/emoji/1/1_1/1.png
 
-    // snprintf(path, path_len,
-    //          "%s%s/%s_%s/%s%s",
-    //          EMOJI_CACHE_BASE_PATH,
-    //          pkg->characterId,
-    //          pkg->eyesColor,
-    //          pkg->eyesShape,
-    //          emoji->emotion,
-    //          ext);
-    // 暂时将文件存在EMOJI_CACHE_BASE_PATH下
-
-    snprintf(path, path_len, "%s%s%s", EMOJI_CACHE_BASE_PATH, emoji->emotion, ext);
+    snprintf(path, path_len,
+             "%s%s/%s_%s/%s%s",
+             EMOJI_CACHE_BASE_PATH,
+             pkg->characterId,
+             pkg->eyesColor,
+             pkg->eyesShape,
+             emoji->emotion,
+             ext);
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] 生成表情缓存路径成功,path=%s", path);
 }
 
@@ -132,6 +129,20 @@ static void ln_emoji_download(void *arg)
         // 下载并缓存
         char save_path[MAX_PATH_LEN] = {0};
         ln_gen_emoji_cache_path(pkg, &pkg->emojis[i], save_path, sizeof(save_path));
+        /* 确保保存目录存在 */
+        {
+            char dir_buf[MAX_PATH_LEN] = {0};
+            const char *last_slash = strrchr(save_path, '/');
+            if (last_slash && last_slash != save_path)
+            {
+                size_t dir_len = (size_t)(last_slash - save_path);
+                if (dir_len >= sizeof(dir_buf))
+                    dir_len = sizeof(dir_buf) - 1;
+                memcpy(dir_buf, save_path, dir_len);
+                dir_buf[dir_len] = '\0';
+                uapi_create_folder(dir_buf);
+            }
+        }
         if (uapi_ln_download_file(pkg->emojis[i].emojiUrl, save_path) != ERRCODE_SUCC)
         {
             all_success = 0;
@@ -143,7 +154,8 @@ static void ln_emoji_download(void *arg)
 
     // 下载完成后上报状态
     const char *status = all_success ? "success" : "failed";
-    do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_EMOJI_REPORT, (char *)status, strlen(status));
+    /* 传递包含'\0'的长度,确保下游按字符串安全处理 */
+    do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_EMOJI_REPORT, (char *)status, (uint32_t)(strlen(status) + 1));
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] report status %s, all_success: %d", status, all_success);
 
     g_emoji_downloading = 0;
@@ -281,6 +293,9 @@ void ln_parse_download_emoji(const char *json_buf, int json_len)
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "  eyesShape: %s", g_emoji_package.eyesShape);
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "  emojiCount: %d", g_emoji_package.emojiCount);
 
+    // 通知UI切换表情
+    // push_download_emoji_notification(g_emoji_package.characterId, g_emoji_package.eyesColor, g_emoji_package.eyesShape);
+
     for (int i = 0; i < g_emoji_package.emojiCount; i++)
     {
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "  emoji %d: emotion=%s, url=%s",
index 75a9806..cd97552 100644 (file)
@@ -129,13 +129,26 @@ void push_character_config_change_notification(const char* characterId,
 //通知ui跳转哄睡界面
 void push_sleep_mode_start_notification(const char *storyTheme)
 {
-    SendMsgToUIService(HAND_SLEEP_MODE_START_NOTIFY, 0, (void *)storyTheme, (int32_t)strlen(storyTheme));
+    /* 发送包含字符串结束符,避免接收端以%s打印读取越界产生乱码 */
+    SendMsgToUIService(HAND_SLEEP_MODE_START_NOTIFY, 0, (void *)storyTheme, (int32_t)(strlen(storyTheme) + 1));
 }
 //通知ui跳转哄睡界面结束
 void push_sleep_mode_end_notification(void)
 {
     SendMsgToUIService(HAND_SLEEP_MODE_END_NOTIFY, 0, NULL, 0);
 }
+//通知ui下载表情
+void push_download_emoji_notification(char *characterId, char *eyesColor, char *eyesShape)
+{
+    char payload[512] = {0};
+    const char *id = characterId ? characterId : "";
+    const char *ec = eyesColor ? eyesColor : "";
+    const char *es = eyesShape ? eyesShape : "";
+    printf("push_download_emoji_notification: characterId=%s, eyesColor=%s, eyesShape=%s\r\n", id, ec, es);
+    (void)snprintf(payload, sizeof(payload) - 1, "%s|%s|%s", id, ec, es);
+    //切换表情通知ui
+    SendMsgToUIService(HAND_DOWNLOAD_EMOJI_NOTIFY, 0, (void *)payload, (int32_t)strlen(payload));
+}
 #ifdef __cplusplus
 };
 #endif
\ No newline at end of file
index eabfcfd..b2b090c 100644 (file)
@@ -65,6 +65,8 @@ void push_character_config_change_notification(
 void push_sleep_mode_start_notification(const char *storyTheme);
 //通知ui跳转哄睡界面结束
 void push_sleep_mode_end_notification(void);
+//通知ui下载表情
+void push_download_emoji_notification(char *characterId, char *eyesColor, char *eyesShape);
 #ifdef __cplusplus
 }
 #endif