1
authorxue <2144439972@qq.com>
Wed, 11 Mar 2026 09:09:31 +0000 (17:09 +0800)
committerxue <2144439972@qq.com>
Wed, 11 Mar 2026 09:09:31 +0000 (17:09 +0800)
autobuild.sh
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdModel.h
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp
code/sdk/zhihui/leiniao/imsl_ln/ln_api.c
code/sdk/zhihui/leiniao/imsl_ln/ln_api.h
code/sdk/zhihui/leiniao/imsl_ln/ln_api_websocket.c
code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.cpp
code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.h

index 0c07cf4..b825d3d 100644 (file)
@@ -59,7 +59,7 @@ declare -A PROJECT_VERSIONS=(
     ["w9"]="1.3.107" 
     ["lt22"]="1.3.107"
     ["n9"]="1.3.113"
-    ["ln"]="1.0.40"
+    ["ln"]="1.0.41"
     ["lnppp"]="1.1.1"
     ["n9ln"]="1.0.0" 
     
index 10f3c5b..85791cb 100644 (file)
@@ -50,6 +50,22 @@ namespace OHOS
         // 常亮屏刷新定时器(用于压测模式,每50分钟刷新一次,避免1小时超时)
         void StartAlwaysOnRefreshTimer();
         void StopAlwaysOnRefreshTimer();
+
+        /** 息屏时间档位:0=30秒(默认) 1=5分钟 2=10分钟 3=30分钟 4=常亮(不息屏);KV 仅存 screen_timeout_sec */
+        static constexpr int SCREEN_KEEPON_LEVEL_30S = 0;
+        static constexpr int SCREEN_KEEPON_LEVEL_5MIN = 1;
+        static constexpr int SCREEN_KEEPON_LEVEL_10MIN = 2;
+        static constexpr int SCREEN_KEEPON_LEVEL_30MIN = 3;
+        static constexpr int SCREEN_KEEPON_LEVEL_ALWAYS = 4;
+        int GetScreenKeeponLevel() const { return screenKeeponLevel_; }
+        /** 设置档位并写入 KV,然后应用当前档位 */
+        void SetScreenKeeponLevel(int level);
+        /** 仅将当前档位应用到系统(不写 KV) */
+        void ApplyScreenKeeponLevel();
+        /** 开机时从 KV 读取档位 */
+        void LoadScreenKeeponLevelFromKV();
+        /** 服务端协议 ScreenTimeoutUpdate:单位秒,0 表示不息屏;落 KV 并立即生效 */
+        void SetScreenTimeoutSeconds(uint32_t screenTimeoutSec);
         
         // 故事模式超时定时器(1分钟无文本切换则退出)
         void StartStoryModeTimeoutTimer(void);
@@ -362,6 +378,8 @@ namespace OHOS
         // 哄睡界面相关标志
         bool m_lullabyView3InquiryStarted = false; // THUNDERBIRD_LULLABYVIEW_3界面,角色是否已经开始询问
 
+        // 息屏时间档位:0=30秒 1=5分钟 2=10分钟 3=1小时 4=常亮
+        int screenKeeponLevel_{SCREEN_KEEPON_LEVEL_30S};
         //音量
         int16_t m_volume = 50;
         // cat1模组版本
index fe14676..0b8ec3c 100644 (file)
@@ -148,8 +148,10 @@ extern "C" {
          // 记录开机时间
          time(&m_bootTime);
 
-         uapi_setScreenDuration(30000);//自动息屏30秒
+        //  uapi_setScreenDuration(30000);//自动息屏30秒
          Readlocalconfig();
+         LoadScreenKeeponLevelFromKV();
+         ApplyScreenKeeponLevel();
 
          last_eyesShape_ = eyesShape_;
          last_hairColor_ = hairColor_;
@@ -1506,6 +1508,104 @@ extern "C" {
         }
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DEVICE_CHARACTER] read character config success (hasScreenImage_=%d from KV, kvRet=%d)", hasScreenImage_, kvRet);
     }
+
+    void ThunderBirdModel::LoadScreenKeeponLevelFromKV()
+    {
+        // 仅使用一个 KV:screen_timeout_sec(秒)。协议只会下发:30/300/600/1800/0(0=不息屏)
+        char temp[16] = {0};
+        int kvRet = UtilsGetValue("screen_timeout_sec", temp, sizeof(temp));
+        int sec = 30;
+        if (kvRet >= 0 && temp[0] != '\0') {
+            sec = atoi(temp);
+        }
+        if (sec <= 0) {
+            screenKeeponLevel_ = SCREEN_KEEPON_LEVEL_ALWAYS;
+            sec = 0;
+        } else if (sec == 30) {
+            screenKeeponLevel_ = SCREEN_KEEPON_LEVEL_30S;
+        } else if (sec == 5 * 60) {
+            screenKeeponLevel_ = SCREEN_KEEPON_LEVEL_5MIN;
+        } else if (sec == 10 * 60) {
+            screenKeeponLevel_ = SCREEN_KEEPON_LEVEL_10MIN;
+        } else if (sec == 30 * 60) {
+            screenKeeponLevel_ = SCREEN_KEEPON_LEVEL_30MIN;
+        } else {
+            // 不会有其他档位,兜底回 30 秒
+            screenKeeponLevel_ = SCREEN_KEEPON_LEVEL_30S;
+            sec = 30;
+        }
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[ScreenKeepon] LoadScreenKeeponLevelFromKV: sec=%d => level=%d (kvRet=%d)", sec, screenKeeponLevel_, kvRet);
+    }
+
+    void ThunderBirdModel::ApplyScreenKeeponLevel()
+    {
+        uint32_t ms = 30 * 1000; /* 默认 30 秒 */
+        switch (screenKeeponLevel_) {
+            case SCREEN_KEEPON_LEVEL_30S:    ms = 30 * 1000; break;
+            case SCREEN_KEEPON_LEVEL_5MIN:   ms = 5 * 60 * 1000; break;
+            case SCREEN_KEEPON_LEVEL_10MIN:  ms = 10 * 60 * 1000; break;
+            case SCREEN_KEEPON_LEVEL_30MIN:  ms = 30 * 60 * 1000; break;
+            case SCREEN_KEEPON_LEVEL_ALWAYS: ms = 30 * 60 * 1000; break; /* 不息屏:auto_off 设置为 30 分钟,常亮由 ScreenAlwaysOnCtr 保证 */
+            default: break;
+        }
+
+        // 常亮档位:开启常亮控制,并启动刷新避免 1 小时超时
+        if (screenKeeponLevel_ == SCREEN_KEEPON_LEVEL_ALWAYS) {
+            ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON);
+            StartAlwaysOnRefreshTimer();
+        } else {
+            ScreenAlwaysOnCtr(CANCEL_SCREEN_ALWAYS_ON);
+            StopAlwaysOnRefreshTimer();
+        }
+
+        uapi_setScreenDuration(static_cast<int32_t>(ms));
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[ScreenKeepon] ApplyScreenKeeponLevel: level=%d, ms=%u", screenKeeponLevel_, (unsigned)ms);
+    }
+
+    void ThunderBirdModel::SetScreenKeeponLevel(int level)
+    {
+        if (level < SCREEN_KEEPON_LEVEL_30S || level > SCREEN_KEEPON_LEVEL_ALWAYS) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[ScreenKeepon] SetScreenKeeponLevel: invalid level=%d, ignore", level);
+            return;
+        }
+        screenKeeponLevel_ = level;
+        // 仅保留一个 KV:screen_timeout_sec(秒)
+        const char *secStr = "30";
+        if (level == SCREEN_KEEPON_LEVEL_5MIN) secStr = "300";
+        else if (level == SCREEN_KEEPON_LEVEL_10MIN) secStr = "600";
+        else if (level == SCREEN_KEEPON_LEVEL_30MIN) secStr = "1800";
+        else if (level == SCREEN_KEEPON_LEVEL_ALWAYS) secStr = "0";
+        (void)UtilsSetValue("screen_timeout_sec", secStr);
+        ApplyScreenKeeponLevel();
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[ScreenKeepon] SetScreenKeeponLevel: level=%d, saved to KV", level);
+    }
+
+    void ThunderBirdModel::SetScreenTimeoutSeconds(uint32_t screenTimeoutSec)
+    {
+        // 协议只会下发:30/300/600/1800/0(0=不息屏)
+        if (screenTimeoutSec == 0) {
+            screenKeeponLevel_ = SCREEN_KEEPON_LEVEL_ALWAYS;
+        } else if (screenTimeoutSec == 30) {
+            screenKeeponLevel_ = SCREEN_KEEPON_LEVEL_30S;
+        } else if (screenTimeoutSec == 5 * 60) {
+            screenKeeponLevel_ = SCREEN_KEEPON_LEVEL_5MIN;
+        } else if (screenTimeoutSec == 10 * 60) {
+            screenKeeponLevel_ = SCREEN_KEEPON_LEVEL_10MIN;
+        } else if (screenTimeoutSec == 30 * 60) {
+            screenKeeponLevel_ = SCREEN_KEEPON_LEVEL_30MIN;
+        } else {
+            // 不会有其他值,兜底 30 秒
+            screenKeeponLevel_ = SCREEN_KEEPON_LEVEL_30S;
+            screenTimeoutSec = 30;
+        }
+
+        char buf[16] = {0};
+        (void)snprintf(buf, sizeof(buf) - 1, "%u", (unsigned)screenTimeoutSec);
+        (void)UtilsSetValue("screen_timeout_sec", buf);
+
+        ApplyScreenKeeponLevel();
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[ScreenKeepon] SetScreenTimeoutSeconds: sec=%u => level=%d", (unsigned)screenTimeoutSec, screenKeeponLevel_);
+    }
     
     // 解析JSON中的data数据
     void ThunderBirdModel::ParseCharacterConfigData(const char* jsonData)
index 26beecc..56c7b35 100644 (file)
@@ -26,6 +26,7 @@
 #include "bluetooth/Ln_Bluetooth_apiC.h"
 #include "cat1_tcpServer.h"
 #include "ln_audio_simple.h"
+#include "ln_api_interface.h"
 // 声明播放器消息处理函数
 
 static app_task_definition_t ln_send_taskcfg = {0};
@@ -1172,6 +1173,27 @@ void ln_ws_process_message(const ws_data_msg_t *data_msg, ws_command_t type)
         push_vad_initialized_notification();
         break;
     }
+    case WS_CMD_SCREEN_TIMEOUT_UPDATE:
+    {
+        // {"command":"ScreenTimeoutUpdate","data":{"screenTimeout":30}}
+        if (json_str) {
+            cJSON *root = cJSON_Parse(json_str);
+            if (root) {
+                cJSON *data_obj = cJSON_GetObjectItem(root, "data");
+                cJSON *screenTimeout = (data_obj && cJSON_IsObject(data_obj)) ? cJSON_GetObjectItem(data_obj, "screenTimeout") : NULL;
+                if (screenTimeout && cJSON_IsNumber(screenTimeout)) {
+                    int sec = screenTimeout->valueint;
+                    if (sec < 0) sec = 0;
+                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[WS] ScreenTimeoutUpdate: screenTimeout=%d", sec);
+                    push_screen_timeout_update_notification((uint32_t)sec);
+                } else {
+                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[WS] ScreenTimeoutUpdate: screenTimeout missing/invalid");
+                }
+                cJSON_Delete(root);
+            }
+        }
+        break;
+    }
     default:
     {
         printf("[WS] Unknown command=%s\n", cmd_str ? cmd_str : "");
index 21a19df..9c8c4d6 100644 (file)
@@ -28,7 +28,7 @@ typedef struct
 
 /* ============================== 公共宏与URL路径 ============================== */
 #define LN_VOICE_CHAT_ENABLED 0  //声纹锁开启宏
-#define LN_ENV_PRODUCTION 1  //正式环境
+#define LN_ENV_PRODUCTION 0  //正式环境
 /* 接口基础配置 - 如需切换环境/密钥,在此调整 */
 #if LN_ENV_PRODUCTION
 #define LN_BASE_URL "https://ambybox-o.api.leiniao.com/ambybox-device-api"   //正式环境服务器地址
@@ -514,6 +514,7 @@ typedef enum {
     WS_CMD_CANCEL_DOWNLOAD_EMOJI, /* 取消下载表情(CancelDownloadEmoji) */
     WS_CMD_CANCEL_DOWNLOAD_EMOJI_ACK, /* 取消下载表情应答(CancelDownloadEmojiAck) - 发送 */
     WS_CMD_TTS_AUDIO_SETTING, /* TTS音频设置(TTSAudioSetting) */
+    WS_CMD_SCREEN_TIMEOUT_UPDATE, /* 息屏时间更新(ScreenTimeoutUpdate) */
     WS_CMD_MAX                       /* 最大命令 */
 } ws_command_t;
 
index ac09a8f..30773fd 100644 (file)
@@ -2185,6 +2185,8 @@ static ws_command_t ln_ws_parse_command_string(const char *command_str)
         return WS_CMD_CANCEL_DOWNLOAD_EMOJI_ACK;
     } else if (strcmp(command_str, "TTSAudioSetting") == 0) {
         return WS_CMD_TTS_AUDIO_SETTING;
+    } else if (strcmp(command_str, "ScreenTimeoutUpdate") == 0) {
+        return WS_CMD_SCREEN_TIMEOUT_UPDATE;
     } else {
         return WS_CMD_UNKNOWN;
     }
index 694ecbb..aa01a03 100644 (file)
@@ -101,6 +101,12 @@ void push_task_reminder_notification(const char *scheduleName)
     SendMsgToUIService(HAND_TASK_REMINDER_NOTIFY, 0,(void *)scheduleName, (int32_t)strlen(scheduleName));
 }
 
+void push_screen_timeout_update_notification(uint32_t screenTimeoutSec)
+{
+    // 不涉及 UI 组件操作,仅设置息屏档位与落 KV,可直接调用
+    OHOS::ThunderBirdModel::GetInstance()->SetScreenTimeoutSeconds(screenTimeoutSec);
+}
+
 // 内存管理相关C接口实现
 static std::string g_memory_info_cache;
 
index 8bc8e44..4a86abe 100644 (file)
@@ -59,6 +59,9 @@ void push_schedule_reminder_notification(const char *title, const char *content)
 // 推送任务提醒
 void push_task_reminder_notification(const char *scheduleName);
 
+/* ScreenTimeoutUpdate:服务端推送息屏时间更新(秒);0 表示不息屏 */
+void push_screen_timeout_update_notification(uint32_t screenTimeoutSec);
+
 // 内存管理相关C接口
 const char* get_system_memory_info(void);
 uint64_t get_folder_size(const char *folder_path);