676 lines
22 KiB
C++
676 lines
22 KiB
C++
#include "TjdUiAppLefunAiModel.h"
|
||
#include "TjdUiAppLefunAiPresenter.h"
|
||
#include "TjdUiAppLefunAiView.h"
|
||
#include "TjdUiImageIds.h"
|
||
#include "TjdUiScreenManage.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 "sql_setting.h"
|
||
#include "sys_config.h"
|
||
#include "thread_adapter.h"
|
||
#include <atomic>
|
||
#include <cstring>
|
||
#include <dirent.h>
|
||
#include <fstream>
|
||
#include <iomanip>
|
||
#include <iostream>
|
||
#include <sstream>
|
||
#include <string>
|
||
#include <vector>
|
||
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_error(...) sys_ui_log_e(__VA_ARGS__) // 错误信息打印一般常开
|
||
#define static_print_debug(...) sys_ui_log_d(__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_SCREEN_AUTO_OFF_TIME (1000 * 60 * 60)
|
||
static MutexId g_lefun_ai_mutex = 0;
|
||
static bool story_question_flag = false;
|
||
static bool story_answer_flag = false;
|
||
struct data_flow *data_flow = nullptr;
|
||
std::string question = "";
|
||
std::string answer = "";
|
||
extern osThreadId_t resend_audio_data_id;
|
||
|
||
int TjdUiAppLefunAiModel::file_exists()
|
||
{
|
||
FILE *file = fopen(LEFUN_AI_STORY_FILE_PATH, "r");
|
||
if (file) {
|
||
fclose(file);
|
||
return 1; // 文件存在
|
||
}
|
||
return 0; // 文件不存在
|
||
}
|
||
|
||
void TjdUiAppLefunAiModel::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 TjdUiAppLefunAiModel::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 TjdUiAppLefunAiModel::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 TjdUiAppLefunAiModel::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 TjdUiAppLefunAiModel::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 TjdUiAppLefunAiModel::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);
|
||
}
|
||
|
||
void TjdUiAppLefunAiModel::AudioInit(void)
|
||
{
|
||
if (audioInitStatus_) {
|
||
static_print_info("LefunAiModel audioInitStatus_ is true");
|
||
return;
|
||
}
|
||
Audio::AudioManager &amIntance = Audio::AudioManager::GetInstance();
|
||
audioInitStatus_ = amIntance.Initialize();
|
||
playerCtr_ = std::make_shared<OHOS::Media::Player>();
|
||
// playerCallback_ = std::make_shared<RecordPlayerCallbackImpl>();
|
||
static_print_info("LefunAiModel AudioInit end!");
|
||
}
|
||
|
||
int TjdUiAppLefunAiModel::RecordStart()
|
||
{
|
||
if (recordIsRuning_) {
|
||
static_print_warn("LefunAiModel 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<LefunAiInterruptListener> recordInterruptListener_ =
|
||
std::make_shared<LefunAiInterruptListener>();
|
||
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<OHOS::Audio::AudioCapturer>();
|
||
|
||
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 * {
|
||
TjdUiAppLefunAiModel::GetInstance().AudioCaptureProcess();
|
||
return nullptr;
|
||
},
|
||
NULL, &attr);
|
||
if (threadIdHandle_ == nullptr) {
|
||
static_print_warn("thread create failed");
|
||
return -1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
void TjdUiAppLefunAiModel::RecordStop()
|
||
{
|
||
static_print_info("RecordStop");
|
||
if (recordIsRuning_) {
|
||
{
|
||
std::lock_guard<std::mutex> 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 TjdUiAppLefunAiModel::AudioCaptureProcess(void)
|
||
{
|
||
static_print_info("TjdUiAppLefunAiModel AudioCaptureProcess start");
|
||
recordIsRuning_ = true;
|
||
while (!needStop_) {
|
||
// 检查是否需要暂停和停止
|
||
std::unique_lock<std::mutex> 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<char *>(buffer), bufferSize)) {
|
||
size_t bytesRead = inputFile.gcount(); // 获取实际读取的字节数
|
||
|
||
if (bytesRead > 8) {
|
||
// 只传输从第9个字节开始的数据
|
||
printf("Read %zu bytes from file\n", bytesRead);
|
||
TjdUiAppLefunAiModel::GetInstance().TransmitAudioData(buffer + 8,
|
||
bytesRead - 8); // 发送数据(跳过前8个字节)
|
||
osDelay(20); // 等待20ms,防止数据过快导致传输失败
|
||
}
|
||
}
|
||
|
||
printf("AudioCaptureFromFile end");
|
||
inputFile.close();
|
||
TjdUiAppLefunAiModel::GetInstance().LefunAiRequestEndAudioTransmit();
|
||
osThreadTerminate(resend_audio_data_id);
|
||
}
|
||
|
||
void TjdUiAppLefunAiModel::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 TjdUiAppLefunAiModel::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 TjdUiAppLefunAiModel::RequestIntoLefunAi()
|
||
{
|
||
tjd_lefun_ai_request_into_lefun_ai();
|
||
tjd_ble_upload_ai_func_attribute();
|
||
}
|
||
|
||
void TjdUiAppLefunAiModel::LefunAiRequestIntoAudioTransmit() { tjd_lefun_ai_request_into_audio_transmit(); }
|
||
|
||
void TjdUiAppLefunAiModel::LefunAiRequestStartAudioTransmit() { tjd_lefun_ai_request_start_audio_transmit(); }
|
||
|
||
void TjdUiAppLefunAiModel::LefunAiRequestExitLefunAi() { tjd_lefun_ai_request_exit_lefun_ai(); }
|
||
|
||
void TjdUiAppLefunAiModel::LefunAiRequestEndAudioTransmit() { tjd_lefun_ai_request_end_audio_transmit(); }
|
||
|
||
void TjdUiAppLefunAiModel::TransmitAudioData(uint8_t *data, uint16_t len) { tjd_ble_transmit_audio_data(data, len); }
|
||
|
||
bool TjdUiAppLefunAiModel::GetAiAudioTransFlag() { return tjd_ble_get_ai_audio_trans_flag(); }
|
||
|
||
void lefun_ai_data_callback(struct data_flow *data)
|
||
{
|
||
printf("LefunAiModel data_callback");
|
||
if (data == nullptr)
|
||
return;
|
||
|
||
if (data->data == nullptr) {
|
||
return;
|
||
}
|
||
|
||
data_flow = data;
|
||
|
||
if (data_flow->data_flow_type == 0) {
|
||
story_question_flag = true;
|
||
// TjdUiAppLefunAiModel::question.clear();
|
||
question = std::string((char *)data_flow->data, data_flow->len);
|
||
// TjdUiAppLefunAiModel::question(std::string((char *)data_flow->data));
|
||
printf("LefunAiModel data_callback question:%s\n", question.c_str());
|
||
} else if (data_flow->data_flow_type == 1) {
|
||
story_answer_flag = true;
|
||
// TjdUiAppLefunAiModel::answer.clear();
|
||
// TjdUiAppLefunAiModel::answer.append(std::string((char *)data_flow->data));
|
||
answer += std::string((char *)data_flow->data);
|
||
}
|
||
GraphicService::GetInstance()->PostGraphicEvent([&]() {
|
||
if (story_question_flag && story_answer_flag) {
|
||
TjdUiAppLefunAiView::GetInstance()->ShowView(LEFUN_AI_VIEW_ANSWER_VIEW);
|
||
}
|
||
});
|
||
}
|
||
|
||
static OHOS::GraphicTimer *waiterTimer_ = nullptr; // 运动进行中计时器
|
||
std::atomic<bool> waiterTimerStart(false);
|
||
static void WaiterTimerCallback(void *arg)
|
||
{
|
||
printf("LefunAiModel WaiterTimerCallback\n");
|
||
if (waiterTimerStart.load()) {
|
||
printf("LefunAiModel WaiterTimerCallback start\n");
|
||
waiterTimerStart.store(false);
|
||
waiterTimer_->Stop();
|
||
waiterTimer_->Start();
|
||
return;
|
||
}
|
||
waiterTimerStart.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([&]() {
|
||
History lefunAiHistory;
|
||
TjdUiAppLefunAiModel::GetInstance().loadFromJson(&lefunAiHistory);
|
||
// printf("line = %d=======lefunAiHistory=%d==========\n", __LINE__, lefunAiHistory.total_records);
|
||
story_answer_flag = false;
|
||
TjdUiAppLefunAiModel::GetInstance().addRecord(&lefunAiHistory, question, answer);
|
||
// printf("line = %d=========lefunAiHistory=%d==========\n", __LINE__, lefunAiHistory.total_records);
|
||
TjdUiAppLefunAiModel::GetInstance().saveToJson(&lefunAiHistory, (const char *)"/system/lefun_ai_record.json");
|
||
question.clear();
|
||
answer.clear();
|
||
});
|
||
}
|
||
|
||
void TjdUiAppLefunAiModel::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__);
|
||
TjdUiAppLefunAiModel::GetInstance().loadFromJson(&lefunAiHistory);
|
||
// printf("line = %d=======lefunAiHistory=%d==========\n", __LINE__, lefunAiHistory.total_records);
|
||
story_answer_flag = false;
|
||
TjdUiAppLefunAiModel::GetInstance().addRecord(&lefunAiHistory, question, answer);
|
||
// printf("line = %d=========lefunAiHistory=%d==========\n", __LINE__, lefunAiHistory.total_records);
|
||
TjdUiAppLefunAiModel::GetInstance().saveToJson(&lefunAiHistory, (const char *)"/system/lefun_ai_record.json");
|
||
question.clear();
|
||
answer.clear();
|
||
}
|
||
|
||
void lefun_ai_data_end_callback(struct data_flow *data)
|
||
{
|
||
printf("LefunAiModel lefun_ai_data_end_callback");
|
||
if (data == nullptr)
|
||
return;
|
||
|
||
if (data->data == nullptr) {
|
||
return;
|
||
}
|
||
|
||
GraphicService::GetInstance()->PostGraphicEvent([&]() {
|
||
data_flow = data;
|
||
|
||
if (story_question_flag && story_answer_flag) {
|
||
TjdUiAppLefunAiView::GetInstance()->ShowView(LEFUN_AI_VIEW_ANSWER_VIEW);
|
||
auto AnswerView = LefunAiAnswerView::GetInstance();
|
||
int bottom = AnswerView->answerView_.GetRect().GetBottom();
|
||
AnswerView->answerView_.ScrollBy(0, -bottom);
|
||
printf("LefunAiModel ScrollBy %d\n", -bottom);
|
||
}
|
||
|
||
// if (waiterTimer_ == nullptr) {
|
||
// waiterTimer_ = new OHOS::GraphicTimer(5000, WaiterTimerCallback, (void *)data, false);
|
||
// waiterTimer_->Start();
|
||
// }
|
||
});
|
||
}
|
||
|
||
void TjdUiAppLefunAiModel::RegisterLefunAiDataCallback(lefun_ai_data_callback_t callback)
|
||
{
|
||
register_lefun_ai_data_callback(callback);
|
||
}
|
||
|
||
void TjdUiAppLefunAiModel::UnregisterLefunAiDataCallback() { unregister_lefun_ai_data_callback(); }
|
||
|
||
void TjdUiAppLefunAiModel::RegisterLefunAiDataEndCallback(lefun_ai_data_callback_t callback)
|
||
{
|
||
register_lefun_ai_data_end_callback(callback);
|
||
}
|
||
|
||
void TjdUiAppLefunAiModel::UnregisterLefunAiDataEndCallback() { unregister_lefun_ai_data_end_callback(); }
|
||
|
||
void TjdUiAppLefunAiModel::CloseAutoScreenOff(void)
|
||
{
|
||
const power_display_svr_api_t *handle = power_display_svr_get_api();
|
||
handle->set_screen_set_keepon_timeout(LEFUN_AI_SCREEN_AUTO_OFF_TIME);
|
||
}
|
||
|
||
void TjdUiAppLefunAiModel::OpenAutoScreenOff(void)
|
||
{
|
||
const power_display_svr_api_t *handle = power_display_svr_get_api();
|
||
handle->set_screen_set_keepon_timeout(0);
|
||
// handle->set_screen_set_keepon_timeout(sql_setting_get_close_screen_time() * 1000);
|
||
}
|
||
|
||
} // namespace TJD
|