From: luozheng <1732036298@qq.com> Date: Thu, 9 Oct 2025 02:59:59 +0000 (+0800) Subject: 1.添加表情下载进度通知函数 X-Git-Tag: V1.0.9_20251128_194606_LN~275^2~7 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=07dc41685847b577b2e8d2bd5d6089898cf2c41e;p=mirrors%2FFD230.git 1.添加表情下载进度通知函数 2.添加表情组上报函数,待验证 --- diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.c index cb7eb5062..4bd76c696 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.c @@ -1249,7 +1249,7 @@ static void ln_http_server_send_task(void const *arg) else if (mail.cmd == LN_HTTP_SERVICE_CMD_EMOJI_REPORT_ALL) { printf("LN_HTTP_SERVICE_CMD_EMOJI_REPORT_ALL:上报所有角色表情组状态\n"); - // ln_emoji_report_all(mail.data); + ln_emoji_report_all(); } else if (mail.cmd == LN_HTTP_SERVICE_CMD_DOWNLOAD_SCREEN_IMAGE) { diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h index 4511c05dd..7a761b00d 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h @@ -67,6 +67,7 @@ typedef struct #define LN_DEVICE_ICCID_FILE LN_DATA_PATH "/device_iccid.bin" #define LN_DEVICE_SCREEN_IMAGE_FILE LN_DATA_PATH "/device_screen_image.bin" // 屏保图片文件 #define LN_REMINDER_AUDIO_FILE LN_DATA_PATH "/reminder_audio.mp3" // 日程提醒音频文件 +#define LN_EMOJI_GROUPS_FILE LN_DATA_PATH "/emoji/emoji_groups.json" /* 表情组持久化文件 */ #define LN_CLIENT_PREPARE_SIZE 2 * 1024 #define TEST_MP3_DOWNLOAD 0 // 测试下载mp3 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 90bb7a003..f8131ce18 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_emoji.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_emoji.c @@ -102,6 +102,217 @@ static void ln_free_emoji_list() g_emoji_package.totalSize = 0; } +/* 读取整个文件为字符串(成功返回0,失败返回-1;调用者负责free(*out_str))*/ +static int ln_read_file_to_string(const char *file_path, char **out_str) +{ + if (out_str) + *out_str = NULL; + if (!file_path || !out_str) + return -1; + FILE *fp = fopen(file_path, "rb"); + if (!fp) + return -1; + if (fseek(fp, 0, SEEK_END) != 0) + { + fclose(fp); + return -1; + } + long len = ftell(fp); + if (len < 0 || len > (1024 * 1024)) + { + fclose(fp); + return -1; + } + if (fseek(fp, 0, SEEK_SET) != 0) + { + fclose(fp); + return -1; + } + char *buf = (char *)malloc((size_t)len + 1); + if (!buf) + { + fclose(fp); + return -1; + } + size_t n = fread(buf, 1, (size_t)len, fp); + fclose(fp); + buf[n] = '\0'; + *out_str = buf; + return 0; +} + +/* 将字符串写入文件(成功返回0,失败返回-1)*/ +static int ln_write_string_to_file(const char *file_path, const char *str) +{ + if (!file_path || !str) + return -1; + /* 确保目录存在 */ + uapi_create_folder((char *)LN_DATA_PATH); + uapi_create_folder((char *)(LN_DATA_PATH "/emoji")); + FILE *fp = fopen(file_path, "wb"); + if (!fp) + return -1; + size_t len = strlen(str); + size_t n = fwrite(str, 1, len, fp); + fclose(fp); + return (n == len) ? 0 : -1; +} + +/* 加载表情组根对象(包含emojiGroups数组);不存在则创建默认结构 */ +static cJSON *ln_load_emoji_groups_root(void) +{ + char *content = NULL; + if (ln_read_file_to_string(LN_EMOJI_GROUPS_FILE, &content) == 0 && content) + { + cJSON *root = cJSON_Parse(content); + free(content); + if (root) + return root; + } + /* 文件不存在或解析失败,创建默认 */ + cJSON *root = cJSON_CreateObject(); + if (!root) + return NULL; + cJSON *arr = cJSON_CreateArray(); + if (!arr) + { + cJSON_Delete(root); + return NULL; + } + cJSON_AddItemToObject(root, "emojiGroups", arr); + return root; +} + +/* 保存根对象到磁盘 */ +static int ln_save_emoji_groups_root(cJSON *root) +{ + if (!root) + return -1; + char *json = cJSON_PrintUnformatted(root); + if (!json) + return -1; + int ret = ln_write_string_to_file(LN_EMOJI_GROUPS_FILE, json); + cJSON_free(json); + return ret; +} + +/* 获取或创建数组 */ +static cJSON *ln_get_or_create_groups_array(cJSON *root) +{ + if (!root) + return NULL; + cJSON *arr = cJSON_GetObjectItem(root, "emojiGroups"); + if (!arr || !cJSON_IsArray(arr)) + { + arr = cJSON_CreateArray(); + if (!arr) + return NULL; + cJSON_ReplaceItemInObject(root, "emojiGroups", arr); + } + return arr; +} + +/* 判断是否已存在条目 */ +static int ln_groups_contains(cJSON *arr, const char *characterId, const char *eyesColor, const char *eyesShape) +{ + if (!arr || !cJSON_IsArray(arr)) + return 0; + int count = cJSON_GetArraySize(arr); + for (int i = 0; i < count; ++i) + { + cJSON *item = cJSON_GetArrayItem(arr, i); + if (!item || !cJSON_IsObject(item)) + continue; + const char *cid = NULL, *color = NULL, *shape = NULL; + cJSON *v = cJSON_GetObjectItem(item, "characterId"); + if (v && cJSON_IsString(v) && v->valuestring) + cid = v->valuestring; + v = cJSON_GetObjectItem(item, "eyesColor"); + if (v && cJSON_IsString(v) && v->valuestring) + color = v->valuestring; + v = cJSON_GetObjectItem(item, "eyesShape"); + if (v && cJSON_IsString(v) && v->valuestring) + shape = v->valuestring; + if (cid && color && shape && + strcmp(cid, characterId ? characterId : "") == 0 && + strcmp(color, eyesColor ? eyesColor : "") == 0 && + strcmp(shape, eyesShape ? eyesShape : "") == 0) + { + return 1; + } + } + return 0; +} + +/* 添加表情组到持久化 */ +static void ln_persist_add_emoji_group(const char *characterId, const char *eyesColor, const char *eyesShape) +{ + cJSON *root = ln_load_emoji_groups_root(); + if (!root) + return; + cJSON *arr = ln_get_or_create_groups_array(root); + if (!arr) + { + cJSON_Delete(root); + return; + } + if (!ln_groups_contains(arr, characterId, eyesColor, eyesShape)) + { + cJSON *item = cJSON_CreateObject(); + if (item) + { + cJSON_AddStringToObject(item, "characterId", characterId ? characterId : ""); + cJSON_AddStringToObject(item, "eyesColor", eyesColor ? eyesColor : ""); + cJSON_AddStringToObject(item, "eyesShape", eyesShape ? eyesShape : ""); + cJSON_AddItemToArray(arr, item); + (void)ln_save_emoji_groups_root(root); + } + } + cJSON_Delete(root); +} + +/* 从持久化中移除表情组 */ +static void ln_persist_remove_emoji_group(const char *characterId, const char *eyesColor, const char *eyesShape) +{ + cJSON *root = ln_load_emoji_groups_root(); + if (!root) + return; + cJSON *arr = ln_get_or_create_groups_array(root); + if (!arr) + { + cJSON_Delete(root); + return; + } + int count = cJSON_GetArraySize(arr); + for (int i = 0; i < count; ++i) + { + cJSON *item = cJSON_GetArrayItem(arr, i); + if (!item || !cJSON_IsObject(item)) + continue; + const char *cid = NULL, *color = NULL, *shape = NULL; + cJSON *v = cJSON_GetObjectItem(item, "characterId"); + if (v && cJSON_IsString(v) && v->valuestring) + cid = v->valuestring; + v = cJSON_GetObjectItem(item, "eyesColor"); + if (v && cJSON_IsString(v) && v->valuestring) + color = v->valuestring; + v = cJSON_GetObjectItem(item, "eyesShape"); + if (v && cJSON_IsString(v) && v->valuestring) + shape = v->valuestring; + if (cid && color && shape && + strcmp(cid, characterId ? characterId : "") == 0 && + strcmp(color, eyesColor ? eyesColor : "") == 0 && + strcmp(shape, eyesShape ? eyesShape : "") == 0) + { + /* 删除该元素 */ + cJSON_DeleteItemFromArray(arr, i); + (void)ln_save_emoji_groups_root(root); + break; + } + } + cJSON_Delete(root); +} + /* 工具函数:生成表情缓存路径 */ static void ln_gen_emoji_cache_path(const EmojiPackage *pkg, const EmotionEmoji *emoji, char *path, size_t path_len) { @@ -217,6 +428,9 @@ static void ln_emoji_download(void *arg) else { downloaded_count++; + /* 表情进度上报,按下载成功表情数量计算 */ + int progress = (int)(((double)downloaded_count / pkg->emojiCount) * 100); + push_download_progress_notification(progress); WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] emoji %s 下载完成", pkg->emojis[i].emotion); } } @@ -246,6 +460,14 @@ static void ln_emoji_download(void *arg) /* 下载完释放本次表情包占用的内存 */ ln_free_emoji_list(); + + /* 持久化:仅在整个表情组下载成功时记录该表情组 */ + if (all_success) + { + /* 通知ui下载成功 */ + push_download_success_notification(DOWNLOAD_FILE_TYPE_EMOJI); + ln_persist_add_emoji_group(mail.characterId, mail.eyesColor, mail.eyesShape); + } } /* 启动表情下载任务 */ @@ -555,6 +777,12 @@ void ln_parse_delete_emoji(const char *json_buf, int json_len) // 清理资源 cJSON_Delete(root); free(text); + + /* 持久化:删除成功则从持久化列表中移除该表情组 */ + if (ret == 0) + { + ln_persist_remove_emoji_group(del_characterId, del_eyesColor, del_eyesShape); + } } /* 7.1 上报角色表情组下载状态(支持 description) */ @@ -758,7 +986,7 @@ static uint32_t ln_emoji_report_all_http(const char *device_id, if (!body) return ERRCODE_FAIL; - HTTPC_RESULT prep = ln_http_prepare_auto(&clientData, 2048, 8 * 1024); + HTTPC_RESULT prep = ln_http_prepare_auto(&clientData, 2048, LN_CLIENT_PREPARE_SIZE * 2); if (prep != HTTP_SUCCESS) { free(body); @@ -768,6 +996,9 @@ static uint32_t ln_emoji_report_all_http(const char *device_id, clientData.postBuf = body; clientData.postBufLen = (int)strlen(body); clientData.postContentType = (char *)"application/json"; + + //打印请求体 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_REPORT_ALL] request body: %s", body); HTTPC_RESULT res = HttpClientPostRequest(&client, LN_EMOJI_REPORT_ALL_URL, &clientData); if (res != HTTP_SUCCESS) @@ -779,6 +1010,14 @@ static uint32_t ln_emoji_report_all_http(const char *device_id, } int code = HttpClientGetResponseCode(&client); + if (code != 200) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_REPORT_ALL] HTTP %d", code); + free(body); + HttpClientUnprepare(&clientData); + free(header_buf); + return ERRCODE_FAIL; + } if (clientData.responseBuf && clientData.responseBufLen > 0) { int real_len = clientData.responseContentLen > 0 ? clientData.responseContentLen : clientData.responseBufLen; @@ -793,13 +1032,6 @@ static uint32_t ln_emoji_report_all_http(const char *device_id, WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_REPORT_STATUS] response body: %s", response_buf); free(response_buf); } - if (code != 200) - { - free(body); - HttpClientUnprepare(&clientData); - free(header_buf); - return ERRCODE_FAIL; - } free(body); HttpClientUnprepare(&clientData); @@ -837,8 +1069,51 @@ void ln_emoji_report_status(char* data) /* 上报所有角色表情组状态 */ void ln_emoji_report_all(void) { - ln_emoji_report_all_http(uapi_ln_get_device_id(), - uapi_ln_get_device_token(), - g_emoji_package.emojis, - g_emoji_package.emojiCount); + const char *device_id = uapi_ln_get_device_id(); + const char *device_token = uapi_ln_get_device_token(); + if (!device_id || !device_token) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_REPORT_ALL] missing device id/token"); + return; + } + + cJSON *root = ln_load_emoji_groups_root(); + if (!root) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_REPORT_ALL] load root failed"); + return; + } + cJSON *arr = ln_get_or_create_groups_array(root); + int count = (arr && cJSON_IsArray(arr)) ? cJSON_GetArraySize(arr) : 0; + if (count < 0) + count = 0; + + LnEmojiGroup *groups = NULL; + if (count > 0) + { + groups = (LnEmojiGroup *)calloc((size_t)count, sizeof(LnEmojiGroup)); + if (!groups) + { + cJSON_Delete(root); + return; + } + for (int i = 0; i < count; ++i) + { + cJSON *item = cJSON_GetArrayItem(arr, i); + cJSON *v = NULL; + v = cJSON_GetObjectItem(item, "characterId"); + groups[i].characterId = (v && cJSON_IsString(v)) ? v->valuestring : ""; + v = cJSON_GetObjectItem(item, "eyesColor"); + groups[i].eyesColor = (v && cJSON_IsString(v)) ? v->valuestring : ""; + v = cJSON_GetObjectItem(item, "eyesShape"); + groups[i].eyesShape = (v && cJSON_IsString(v)) ? v->valuestring : ""; + groups[i].status = "download_success"; /* 当前设备上已安装的表情组 */ + } + } + + (void)ln_emoji_report_all_http(device_id, device_token, groups, count); + + if (groups) + free(groups); + cJSON_Delete(root); } \ No newline at end of file diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_story_random.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_story_random.c index e7cf97c6f..a6e289e43 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_story_random.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_story_random.c @@ -269,7 +269,7 @@ void ln_parse_voice_chat_response(const char *json_str, int json_len) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始哄睡\n"); push_sleep_mode_start_notification(NULL, 1); // 1意图识别结果 - ln_ws_send_random_story_request(NULL); + ln_ws_send_random_story_request("随机故事"); } else if(strcmp(intention_str, "EndSleepMode") == 0) { 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 a656a7c01..3b5d5a5a9 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 @@ -240,6 +240,11 @@ void push_download_success_notification(int type) SendMsgToUIService(HAND_DOWNLOAD_SUCCESS_NOTIFY, 0, &type, sizeof(type)); } +// 推送文件下载进度通知到UI +void push_download_progress_notification(int progress) +{ +} + #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 1f9fb39f4..a656ed7ec 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 @@ -94,6 +94,8 @@ enum { void push_download_file_notification(int type); // 推送文件下载成功通知到UI void push_download_success_notification(int type); +// 推送文件下载进度通知到UI +void push_download_progress_notification(int progress); #ifdef __cplusplus } #endif