/*---------------------------------------------------------------------------- * Copyright (c) TJD Technologies Co., Ltd. 2024. All rights reserved. * * Description: TjdUiAppPlayDialModel.cpp * * Author: liuguanwu * * Create: 2024-10 *--------------------------------------------------------------------------*/ #include "TjdUiAppPlayDialModel.h" #include "TjdUiAppPlayDialPresenter.h" #include "TjdUiAppPlayDialView.h" #include "TjdUiImageIds.h" #include "TjdUiScreenManage.h" #include "audio_capturer.h" #include "ble_port_protocol.h" #include "cJSON.h" #include "common/image_cache_manager.h" #include "graphic_service.h" #include "hal_tick.h" #include "power_display_service.h" #include "rtc_api.h" #include "sql_setting.h" #include "sys_config.h" #include "sys_typedef.h" #include "thread_adapter.h" #include #include #include #include #include #include #include #include #include #include #include namespace TJD { #define ENABLE_PRINT_INFO 0 #if ENABLE_PRINT_INFO #define static_print_info(...) sys_ui_log_i(__VA_ARGS__) // 一般信息打印宏控制 #define static_print_warn(...) sys_ui_log_w(__VA_ARGS__) // 警告信息打印一般常开 #define static_print_debug(...) sys_ui_log_d(__VA_ARGS__) // 调试信息打印一般常开 #define static_print_error(...) sys_ui_log_e(__VA_ARGS__) // 错误信息打印一般常开 #else #define static_print_info(...) #define static_print_warn(...) #define static_print_error(...) #define static_print_debug(...) #endif #define LOAD_BUFFER_SIZE 8 * 1024 #define LEFUN_AI_STORY_FILE_PATH "/user/tjd_wfp/lefun_ai_record.json" // TJD_FS_DIR_WFP #define TJD_DIAL_WF_CONFIG_PATH "/user/tjd_wf/wf_config_0.json" #define TJD_FS_DIR_WFP_E TJD_FS_DIR_WFP "/" static MutexId g_lefun_ai_mutex = 0; static bool story_question_flag = false; static bool story_answer_flag = false; static struct data_flow *data_flow = nullptr; static std::shared_ptr lefunAiCapturer_{nullptr}; std::string g_PlayDialQuestion = ""; std::string g_PlayDialAnswer = ""; std::string g_PlayDialPath = ""; std::string g_PlayDialPreviewPath = ""; extern osThreadId_t resend_audio_data_id; TjdUiAppPlayDialModel::TjdUiAppPlayDialModel() { wfFileList.clear(); } TjdUiAppPlayDialModel::~TjdUiAppPlayDialModel() { for (int16_t i = 0; i < wfFileList.size(); i++) { OHOS::ImageCacheManager::GetInstance().UnloadSingleRes(wfFileList.data()[i]); } wfFileList.clear(); } int TjdUiAppPlayDialModel::FileExists(const char *filename) { FILE *file = fopen(filename, "r"); if (file) { fclose(file); return 1; // 文件存在 } return 0; // 文件不存在 } int TjdUiAppPlayDialModel::FileDelete(const char *filename) { return unlink(filename); } void TjdUiAppPlayDialModel::addRecord(History *history, std::string question, std::string answer) { if (history == nullptr || history->records == nullptr) { return; } if (history->total_records >= MAX_HISTORY) { for (int i = 1; i < MAX_HISTORY; i++) { history->records[i - 1] = history->records[i]; } history->total_records--; } if (history->total_records < MAX_HISTORY) { history->records[history->total_records].question = question; history->records[history->total_records].answer = answer; history->total_records++; } } void TjdUiAppPlayDialModel::saveToJson(const History *history, const char *filename) { // 检查输入参数 if (!history || history->total_records < 0) { printf("Error: Invalid history object\n"); return; } // 创建 JSON 对象 cJSON *json = cJSON_CreateObject(); if (!json) { printf("Error creating JSON object\n"); return; } // 创建历史记录数组 cJSON *historyArray = cJSON_CreateArray(); if (!historyArray) { printf("Error creating JSON array\n"); cJSON_Delete(json); return; } // 将 total_records 添加到 JSON 对象中 cJSON_AddNumberToObject(json, "total_records", history->total_records); // 遍历历史记录并添加到 JSON 数组中 for (int i = 0; i < history->total_records; i++) { const std::string &question = history->records[i].question; const std::string &answer = history->records[i].answer; cJSON *item = cJSON_CreateObject(); if (!item) { printf("Error creating JSON item for record \n"); continue; } if (item == nullptr) { return; } cJSON_AddStringToObject(item, "question", question.c_str()); cJSON_AddStringToObject(item, "answer", answer.c_str()); // 将记录添加到历史记录数组 cJSON_AddItemToArray(historyArray, item); } // 将历史记录数组添加到 JSON 对象 cJSON_AddItemToObject(json, "history", historyArray); // 打开文件以写入 JSON 数据 FILE *file = fopen(filename, "w"); if (!file) { printf("Error opening file: "); cJSON_Delete(json); return; } // 将 JSON 对象转换为字符串并写入文件 char *jsonString = cJSON_Print(json); if (jsonString) { fprintf(file, "%s\n", jsonString); free(jsonString); // 释放 JSON 字符串 } // 关闭文件和删除 JSON 对象 fclose(file); cJSON_Delete(json); } void TjdUiAppPlayDialModel::displayHistory(const History *history) { printf("displayHistory %d\n", history->total_records); for (int i = 0; i < history->total_records; i++) { // 打印每个记录的 question 和 answer printf("Record %d:\n", i + 1); printf("Question: %s\n", history->records[i].question.c_str()); printf("Answer: %s\n", history->records[i].answer.c_str()); printf("------------------\n"); } } void TjdUiAppPlayDialModel::loadFromJson(History *history) { char *filename = LEFUN_AI_STORY_FILE_PATH; FILE *file = fopen(filename, "r"); if (!file) { // 文件不存在,创建初始 JSON createInitialJson(filename); return; // 返回以避免进一步处理 } char *buffer = (char *)malloc(LOAD_BUFFER_SIZE); if (!buffer) { printf("Error: Failed to allocate memory for buffer.\n"); fclose(file); return; } size_t bytesRead = fread(buffer, sizeof(char), LOAD_BUFFER_SIZE - 1, file); buffer[bytesRead] = '\0'; fclose(file); cJSON *json = cJSON_Parse(buffer); if (json) { cJSON *totalRecordsItem = cJSON_GetObjectItem(json, "total_records"); history->total_records = totalRecordsItem ? totalRecordsItem->valueint : 0; cJSON *historyArray = cJSON_GetObjectItem(json, "history"); cJSON *record = NULL; int index = 0; // 当前存储记录的索引 cJSON_ArrayForEach(record, historyArray) { if (index < 10) { // 获取问题和答案 cJSON *questionItem = cJSON_GetObjectItem(record, "question"); cJSON *answerItem = cJSON_GetObjectItem(record, "answer"); if (questionItem && questionItem->valuestring && answerItem && answerItem->valuestring) { history->records[index].question = questionItem->valuestring; history->records[index].answer = answerItem->valuestring; index++; } else { fprintf(stderr, "Warning: Missing question or answer in record %d\n", index); } } history->total_records = index; } cJSON_Delete(json); } else { static_print_warn("Error parsing JSON json null\n"); } free(buffer); } uint8_t TjdUiAppPlayDialModel::get_total_records_from_json() { FILE *file = fopen(LEFUN_AI_STORY_FILE_PATH, "r"); if (file == NULL) { printf("Could not open file %s\n", LEFUN_AI_STORY_FILE_PATH); return 0; // 返回 0 表示文件未未初始化,直接返回 } // 获取文件大小 fseek(file, 0, SEEK_END); long length = ftell(file); fseek(file, 0, SEEK_SET); // 读取文件内容 char *data = (char *)malloc(length + 1); fread(data, 1, length, file); data[length] = '\0'; // 确保字符串以 null 结尾 fclose(file); cJSON *json = cJSON_Parse(data); free(data); if (json == NULL) { printf("Error parsing JSON\n"); return -1; // 返回 -1 表示解析错误 } cJSON *total_records_item = cJSON_GetObjectItem(json, "total_records"); uint8_t total_records = total_records_item ? total_records_item->valueint : -1; // 默认返回 -1 cJSON_Delete(json); return total_records; } void TjdUiAppPlayDialModel::createInitialJson(const char *filename) { cJSON *json = cJSON_CreateObject(); cJSON_AddNumberToObject(json, "total_records", 0); cJSON *historyArray = cJSON_CreateArray(); cJSON_AddItemToObject(json, "history", historyArray); FILE *file = fopen(filename, "w"); if (file) { char *jsonString = cJSON_Print(json); fprintf(file, "%s\n", jsonString); free(jsonString); fclose(file); } cJSON_Delete(json); } uint8_t TjdUiAppPlayDialModel::UpdateHistoryFileList(uint8_t max_file) { std::string fullPath; for (int16_t i = 0; i < wfFileList.size(); i++) { OHOS::ImageCacheManager::GetInstance().UnloadSingleRes(wfFileList.data()[i]); } wfFileList.clear(); // 云表盘:打开目录 struct dirent *direntp; DIR *dirp = opendir(TJD_FS_DIR_WFP); // 遍历文件 if (dirp != nullptr) { std::string DirPrePath(TJD_FS_DIR_WFP); while ((direntp = readdir(dirp)) != nullptr) { std::string filename(direntp->d_name); fullPath = TJD_FS_DIR_WFP_E + filename; printf("filename(%s-%s)\n", filename.c_str(), fullPath.c_str()); if (filename.find(".bin") != std::string::npos && filename.find("wfp_bg") != std::string::npos) { std::string number; std::size_t pos1 = filename.find_last_of('_'); if (pos1 != std::string::npos) { // 查找 .bin 的位置 std::size_t pos2 = filename.find(".bwf", pos1); if (pos2 != std::string::npos) { // 提取下划线和 .bin 之间的子字符串 number = filename.substr(pos1 + 1, pos2 - pos1 - 1); static_print_debug("FindWfFile number: %s\n", number.c_str()); } } wfFileList.push_back(fullPath); printf(".bin filename(%s)\n", fullPath.c_str()); } else if (filename.find(".hbm") != std::string::npos && filename.find("wfp_preview") != std::string::npos) { printf(".hbm filename(%s)\n", fullPath.c_str()); } else { FileDelete(fullPath.c_str()); } } } // 关闭目录 closedir(dirp); std::sort(wfFileList.begin(), wfFileList.end(), std::greater()); while (wfFileList.size() > max_file) { FileDelete(wfFileList[wfFileList.size() - 1].c_str()); wfFileList.pop_back(); } printf("wfFileList.size(%d)\n", wfFileList.size()); return wfFileList.size(); } std::vector *TjdUiAppPlayDialModel::GetHistoryFileList() { return &wfFileList; } uint8_t TjdUiAppPlayDialModel::MakeingWfConfig0Json(const char *filename) { if (FileExists(filename) == 0) { static_print_error("Error opening file:[%s]", filename); return -1; } std::string fullPath = filename; if (strcmp(filename, PLAY_DIAL_DRAW_BIN_TEMP_PATH) == 0) { uint64_t timestamp = 0; tjd_driver_rtc_get_ops()->get_timestamp(×tamp); fullPath.clear(); fullPath.append(TJD_FS_DIR_WFP); fullPath.append("/wfp_bg_"); fullPath.append(std::to_string(timestamp)); fullPath.append(".bin"); printf("g_PlayDialPreviewPath rename():%s,%s\n", filename, fullPath.c_str()); // PLAY_DIAL_DRAW_BIN_PATH 不使用固定文件名 if (0 != rename(filename, fullPath.c_str())) { printf("TjdUiAppPlayDialModel:fail rename():%s,%s\n", filename, fullPath.c_str()); fullPath.clear(); return -1; } } // 创建 JSON 对象 cJSON *json = cJSON_CreateObject(); if (!json) { static_print_error("Error creating JSON object"); fullPath.clear(); return -1; } // 将 wf_type 添加到 JSON 对象中 cJSON_AddNumberToObject(json, "wf_type", 0); // cJSON_AddNumberToObject(json, "wf_type", param_data.setting_mode); // 将 wf_preview 添加到 JSON 对象中 cJSON_AddStringToObject(json, "wf_preview", fullPath.c_str()); // 将 bg_res 添加到 JSON 对象中 cJSON_AddStringToObject(json, "bg_res", fullPath.c_str()); // 将 img_number 添加到 JSON 对象中 cJSON_AddNumberToObject(json, "img_number", 1); // 将 video_preview 添加到 JSON 对象中 // cJSON_AddStringToObject(json, "video_preview", TJD_CUSTOM_DIAL_VIDEO_PREVIEW_PATH); cJSON_AddNullToObject(json, "video_preview"); // tjd_set_custom_dial_file_num(0); // tjd_set_custom_dial_file_mask(false); fullPath.clear(); // 打开文件以写入 JSON 数据 FILE *file = fopen(TJD_DIAL_WF_CONFIG_PATH, "w"); if (!file) { static_print_error("Error opening file: "); cJSON_Delete(json); return -1; } // 将 JSON 对象转换为字符串并写入文件 char *jsonString = cJSON_Print(json); if (jsonString) { fprintf(file, "%s\n", jsonString); free(jsonString); // 释放 JSON 字符串 } // 关闭文件和删除 JSON 对象 fclose(file); cJSON_Delete(json); return 0; } void TjdUiAppPlayDialModel::AudioInit(void) { if (audioInitStatus_) { static_print_info("PlayDialModel audioInitStatus_ is true"); return; } Audio::AudioManager &amIntance = Audio::AudioManager::GetInstance(); audioInitStatus_ = amIntance.Initialize(); playerCtr_ = std::make_shared(); // playerCallback_ = std::make_shared(); static_print_info("PlayDialModel AudioInit end!"); } int TjdUiAppPlayDialModel::RecordStart() { printf("TjdUiAppPlayDialModel::RecordStart()\n"); if (recordIsRuning_) { static_print_warn("PlayDialModel RecordStart failed, recordIsRuning_ is true"); return OHOS_FAILURE; } Audio::AudioManager &amIntance = Audio::AudioManager::GetInstance(); if (!isActivateAudioInterrupt_) { static_print_info("ActivateAudioInterrupt"); // 申请焦点 sessionId_ = amIntance.MakeSessionId(); if (sessionId_ == AUDIO_SESSION_ID_NONE) { static_print_warn("session invalid"); return OHOS_FAILURE; } std::shared_ptr recordInterruptListener_ = std::make_shared(); interrupt_ = {AUDIO_STREAM_VOICE_RECORD, sessionId_, recordInterruptListener_}; // 激活音频中断 5s超时 if (amIntance.ActivateAudioInterrupt(interrupt_) == INTERRUPT_FAILED) { static_print_warn("ActivateAudioInterrupt faild"); return OHOS_FAILURE; } isActivateAudioInterrupt_ = true; } lefunAiCapturer_ = std::make_shared(); url_ = std::string("/user/") + "lefunAi_test.opus"; pfd_.open(url_, std::ios::out | std::ios::binary); if (!pfd_.is_open()) { static_print_warn("open file failed"); lefunAiCapturer_.reset(); (void)amIntance.DeactivateAudioInterrupt(interrupt_); return -1; } // 设置音频参数 OHOS::Audio::AudioCapturerInfo info = {}; info.inputSource = AUDIO_MIC; info.audioFormat = AudioCodecFormat::OPUS; info.sampleRate = 16000; info.channelCount = 1; info.streamType = AUDIO_STREAM_VOICE_RECORD; info.bitWidth = AudioBitWidth::BIT_WIDTH_16; info.sessionID = sessionId_; if (lefunAiCapturer_->SetCapturerInfo(info) != 0) { static_print_warn("{%s,%d} set capturer info failed", __func__, __LINE__); (void)amIntance.DeactivateAudioInterrupt(interrupt_); return -1; } // 获取每帧大小 size_t frameCount = lefunAiCapturer_->GetFrameCount(); if (!frameCount) { static_print_warn("Can't GetFrameCount"); (void)lefunAiCapturer_->Release(); (void)amIntance.DeactivateAudioInterrupt(interrupt_); return -1; } framesize_ = frameCount * info.channelCount * info.bitWidth / 8; static_print_info("framesize_:%d", framesize_); lefunAiRecordBuffer_ = new uint8_t[framesize_]; if (!lefunAiCapturer_->Start()) { static_print_warn("{%s,%d} start failed", __func__, __LINE__); lefunAiCapturer_.reset(); (void)amIntance.DeactivateAudioInterrupt(interrupt_); // delete lefunAiCapturer_; return -1; } recordIsRuning_ = false; MediaThreadattr attr = {"lefun_ai_record", 0x2000, THREAD_SCHED_INVALID, 0, true}; threadIdHandle_ = MediaThreadCreate( [](void *arg) -> void * { TjdUiAppPlayDialModel::GetInstance().AudioCaptureProcess(); return nullptr; }, NULL, &attr); if (threadIdHandle_ == nullptr) { static_print_warn("thread create failed"); return -1; } return 0; } void TjdUiAppPlayDialModel::RecordStop() { printf("TjdUiAppPlayDialModel::RecordStop()\n"); if (recordIsRuning_) { { std::lock_guard lock(pauseMutex_); needStop_.store(true); needPause_.store(false); // 确保线程不会因为暂停而阻塞 } pauseCondVar_.notify_all(); // 唤醒等待的线程 static_print_debug("LefunAi RecordStop wait thread join"); osThreadJoin(threadIdHandle_); static_print_debug("LefunAi RecordStop thread join end"); } LefunAiRequestEndAudioTransmit(); } void TjdUiAppPlayDialModel::AudioCaptureProcess(void) { static_print_info("TjdUiAppPlayDialModel AudioCaptureProcess start"); recordIsRuning_ = true; while (!needStop_) { // 检查是否需要暂停和停止 std::unique_lock lock(pauseMutex_); uint64_t pauseStartTime = OHOS::HALTick::GetInstance().GetTime(); pauseCondVar_.wait(lock, [this] { return !needPause_ || needStop_; }); if (needStop_) { static_print_debug("needStop_ is true"); break; } memset(lefunAiRecordBuffer_, 0, framesize_); ret = lefunAiCapturer_->Read(lefunAiRecordBuffer_, framesize_, false); printf("lefunAiCapturer_->Read ret:%d\n", ret); if (ret == -1) { static_print_warn("audioCap Read failed:0x%x", ret); continue; } if (ret == OHOS::Media::ERR_RETRY_READ) { usleep(10000); continue; } pfd_.write((const char *)lefunAiRecordBuffer_, ret); if (!pfd_) { static_print_warn("errno:%d, errmsg:%s", errno, strerror(errno)); break; } TransmitAudioData(lefunAiRecordBuffer_ + 8, ret - 8); } static_print_info("AudioCaptureProcess end"); pfd_.close(); RecordDestroy(); } static void resend_audio_task(void *argument) { osDelay(500); // 打开文件 std::ifstream inputFile("/user/lefunAi_test.opus", std::ios::in | std::ios::binary); if (!inputFile.is_open()) { printf("Failed to open file: %s", "/user/lefunAi_test.opus"); return; } // 定义缓冲区,每次读取168字节 const size_t bufferSize = 168; uint8_t buffer[168]; // 循环读取文件并发送数据 while (inputFile.read(reinterpret_cast(buffer), bufferSize)) { size_t bytesRead = inputFile.gcount(); // 获取实际读取的字节数 if (bytesRead > 8) { // 只传输从第9个字节开始的数据 printf("Read %zu bytes from file\n", bytesRead); TjdUiAppPlayDialModel::GetInstance().TransmitAudioData(buffer + 8, bytesRead - 8); // 发送数据(跳过前8个字节) osDelay(10); // 等待10ms,防止数据过快导致传输失败 } } printf("AudioCaptureFromFile end"); inputFile.close(); TjdUiAppPlayDialModel::GetInstance().LefunAiRequestEndAudioTransmit(); osThreadTerminate(resend_audio_data_id); } void TjdUiAppPlayDialModel::ResendAudioData() { static_print_info("ResendAudioData start"); osThreadAttr_t task_attr = {"resend_audio_data_task", 0, NULL, 0, NULL, 0x1000, (osPriority_t)17, 0, 0}; resend_audio_data_id = osThreadNew(resend_audio_task, NULL, &task_attr); if (resend_audio_data_id == NULL) { static_print_error("resend_audio_data_task failed"); return; } } void TjdUiAppPlayDialModel::RecordDestroy(void) { static_print_debug("RecordDestroy"); Audio::AudioManager &amIntance = Audio::AudioManager::GetInstance(); MediaMutexLock(g_lefun_ai_mutex); if (!lefunAiCapturer_->Stop()) { static_print_warn("Stop failed"); } if (!lefunAiCapturer_->Release()) { static_print_warn("Release failed"); } delete lefunAiRecordBuffer_; lefunAiRecordBuffer_ = nullptr; if (amIntance.DeactivateAudioInterrupt(interrupt_) != 0) { static_print_warn("deactivate audio interrupt failed"); } needStop_ = false; needPause_ = false; lefunAiCapturer_.reset(); lefunAiCapturer_ = nullptr; isActivateAudioInterrupt_ = false; recordIsRuning_ = false; MediaMutexUnLock(g_lefun_ai_mutex); } void TjdUiAppPlayDialModel::RequestIntoLefunAi() { // tjd_lefun_ai_request_into_lefun_ai(); // tjd_ble_upload_ai_func_attribute(); tjd_lefun_ai_request_into_play_dial(); tjd_ble_upload_play_dial_func_attribute((ai_picture_style_t)(TjdUiAppPlayDialModel::GetInstance().dialStyle_), 0, 0); printf("TjdUiAppPlayDialModel::RequestIntoLefunAi() dialStyle_:%d\n", dialStyle_); } void TjdUiAppPlayDialModel::LefunAiRequestIntoAudioTransmit() { tjd_lefun_ai_request_into_audio_transmit(); } void TjdUiAppPlayDialModel::LefunAiRequestStartAudioTransmit() { tjd_lefun_ai_request_start_audio_transmit(); } void TjdUiAppPlayDialModel::LefunAiRequestExitLefunAi() { // tjd_lefun_ai_request_exit_lefun_ai(); tjd_lefun_ai_request_exit_play_dial(); } void TjdUiAppPlayDialModel::LefunAiRequestEndAudioTransmit() { tjd_lefun_ai_request_end_audio_transmit(); } void TjdUiAppPlayDialModel::LefunAiRequestImageData() { printf("TjdUiAppPlayDialModel::LefunAiRequestImageData()\n"); tjd_play_dial_request_diagram_generation(0, 0); //流id无效,首次传0。 } void TjdUiAppPlayDialModel::LefunAiRequestTransmitImageData() { printf("TjdUiAppPlayDialModel::LefunAiRequestTransmitImageData()\n"); tjd_play_dial_request_diagram_transmit(0); //原图0。 } void TjdUiAppPlayDialModel::TransmitAudioData(uint8_t *data, uint16_t len) { tjd_ble_transmit_audio_data(data, len); } bool TjdUiAppPlayDialModel::GetAiAudioTransFlag() { return tjd_ble_get_ai_audio_trans_flag(); } void TjdUiAppPlayDialModel::lefun_ai_data_callback(struct data_flow *data) { printf("PlayDialModel data_callback"); // static_print_info("PlayDialModel data_callback"); GraphicService::GetInstance()->PostGraphicEvent([&]() { if (data == nullptr || data->data == nullptr) return; data_flow = data; if (data_flow->data_flow_type == 0) { story_question_flag = true; // TjdUiAppPlayDialModel::question.clear(); g_PlayDialQuestion = std::string((char *)data_flow->data, data_flow->len); // TjdUiAppPlayDialModel::g_PlayDialQuestion(std::string((char *)data_flow->data)); printf("PlayDialModel data_callback g_PlayDialQuestion:%s\n", g_PlayDialQuestion.c_str()); } else if (data_flow->data_flow_type == 1) { story_answer_flag = true; // TjdUiAppPlayDialModel::g_PlayDialAnswer.clear(); // TjdUiAppPlayDialModel::g_PlayDialAnswer.append(std::string((char *)data_flow->data)); g_PlayDialAnswer += std::string((char *)data_flow->data); } if (story_question_flag && story_answer_flag) { // TjdUiAppPlayDialView::GetInstance().ShowView(PLAYDIAL_AI_MAKING);//saimen } }); } static OHOS::GraphicTimer *waiterTimer_ = nullptr; // 运动进行中计时器 std::atomic PlayDialWaiterTimerStart(false); static void WaiterTimerCallback(void *arg) { printf("PlayDialModel WaiterTimerCallback\n"); if (PlayDialWaiterTimerStart.load()) { printf("PlayDialModel WaiterTimerCallback start\n"); PlayDialWaiterTimerStart.store(false); waiterTimer_->Stop(); waiterTimer_->Start(); return; } PlayDialWaiterTimerStart.store(false); if (data_flow->data != NULL) { free(data_flow->data); data_flow->data = NULL; } data_flow->len = 0; data_flow->data_flow_id = 0; data_flow->data_flow_type = 0; // 保存历史记录到 JSON 文件 GraphicService::GetInstance()->PostGraphicEvent([&]() { TjdUiAppPlayDialModel::History lefunAiHistory; TjdUiAppPlayDialModel::GetInstance().loadFromJson(&lefunAiHistory); // printf("line = %d=======lefunAiHistory=%d==========\n", __LINE__, lefunAiHistory.total_records); story_answer_flag = false; TjdUiAppPlayDialModel::GetInstance().addRecord(&lefunAiHistory, g_PlayDialQuestion, g_PlayDialAnswer); // printf("line = %d=========lefunAiHistory=%d==========\n", __LINE__, lefunAiHistory.total_records); TjdUiAppPlayDialModel::GetInstance().saveToJson(&lefunAiHistory, LEFUN_AI_STORY_FILE_PATH); g_PlayDialQuestion.clear(); g_PlayDialAnswer.clear(); }); } void TjdUiAppPlayDialModel::DeleDataFlow(void) { if (data_flow->data != NULL) { free(data_flow->data); data_flow->data = NULL; } if (data_flow) { data_flow->len = 0; data_flow->data_flow_id = 0; data_flow->data_flow_type = 0; } // 保存历史记录到 JSON 文件 History lefunAiHistory; // printf("line = %d==================\n", __LINE__); TjdUiAppPlayDialModel::GetInstance().loadFromJson(&lefunAiHistory); // printf("line = %d=======lefunAiHistory=%d==========\n", __LINE__, lefunAiHistory.total_records); story_answer_flag = false; TjdUiAppPlayDialModel::GetInstance().addRecord(&lefunAiHistory, g_PlayDialQuestion, g_PlayDialAnswer); // printf("line = %d=========lefunAiHistory=%d==========\n", __LINE__, lefunAiHistory.total_records); TjdUiAppPlayDialModel::GetInstance().saveToJson(&lefunAiHistory, LEFUN_AI_STORY_FILE_PATH); g_PlayDialQuestion.clear(); g_PlayDialAnswer.clear(); } void TjdUiAppPlayDialModel::lefun_ai_data_end_callback(struct data_flow *data) { printf("TjdUiAppPlayDialModel::lefun_ai_data_end_callback()\n"); TjdUiAppPlayDialView::GetInstance().Result_ = AI_RESULT_SELECT_TXT; PlayDialWaiterTimerStart.store(true); GraphicService::GetInstance()->PostGraphicEvent([&]() { if (data == nullptr || data->data == nullptr) { return; } data_flow = data; if (story_question_flag && story_answer_flag) { // TjdUiAppPlayDialView::GetInstance().ShowView(PLAYDIAL_AI_MAKING);//saimen } // if (waiterTimer_ == nullptr) { // waiterTimer_ = new OHOS::GraphicTimer(5000, WaiterTimerCallback, (void *)data, false); // waiterTimer_->Start(); // } }); } void TjdUiAppPlayDialModel::play_dial_app_ready_callback(bool isSuccess) { printf("TjdUiAppPlayDialModel::play_dial_app_ready_callback():%d\n", isSuccess); TjdUiAppPlayDialView::GetInstance().Result_ = AI_RESULT_APP_DONE; } void TjdUiAppPlayDialModel::play_dial_original_end_callback(char *original_picture_name) { TjdUiAppPlayDialView::GetInstance().Result_ = AI_RESULT_SELECT_IMG; g_PlayDialPath = std::string(original_picture_name); printf("TjdUiAppPlayDialModel::play_dial_original_end_callback():%s-%s\n", original_picture_name, g_PlayDialPath.c_str()); } void TjdUiAppPlayDialModel::RegisterLefunAiDataCallback(lefun_ai_data_callback_t callback) { register_lefun_ai_data_callback(callback); } void TjdUiAppPlayDialModel::UnregisterLefunAiDataCallback() { unregister_lefun_ai_data_callback(); } void TjdUiAppPlayDialModel::RegisterLefunAiDataEndCallback(lefun_ai_data_callback_t callback) { register_lefun_ai_data_end_callback(callback); } void TjdUiAppPlayDialModel::UnregisterLefunAiDataEndCallback() { unregister_lefun_ai_data_end_callback(); } void TjdUiAppPlayDialModel::RegisterAppImageReadyCallback(play_dial_request_generate_picture_callback_t callback) { register_play_dial_request_generate_picture_callback(callback); } void TjdUiAppPlayDialModel::UnregisterAppImageReadyCallback() { unregister_play_dial_request_generate_picture_callback(); } void TjdUiAppPlayDialModel::RegisterOriginalImageEndCallback(play_dial_original_callback_t callback) { register_play_dial_original_callback(callback); } void TjdUiAppPlayDialModel::UnregisterOriginalImageEndCallback() { unregister_play_dial_original_callback(); } } // namespace TJD