增加压测AT指令 3066/1 3066/head 3071/target/1
authorxue <2144439972@qq.com>
Mon, 12 Jan 2026 14:55:10 +0000 (22:55 +0800)
committerxue <2144439972@qq.com>
Mon, 12 Jan 2026 14:55:10 +0000 (22:55 +0800)
code/sdk/application/wearable/ln/nativeapp/nativeui/include/uiservice/ui_service.h
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdModel.h
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp
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/ln_api_cpp/ln_api_interface.cpp
code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.h
code/sdk/zhihui/leiniao/ln_api_cpp/ln_audio_simple.cpp
code/sdk/zhihui/leiniao/ln_api_cpp/ln_audio_simple.h

index 85bba01..44d6aa9 100644 (file)
@@ -78,6 +78,7 @@ typedef enum {
     HAND_VAD_INITIALIZED_NOTIFY, // VAD初始化完成通知
     HAND_BLUETOOTH_CONNECT_NOTIFY, // 蓝牙耳机连接通知
     HAND_BLUETOOTH_EARPHONE_CONNECT_STATUS_NOTIFY,  // 蓝牙耳机连接状态通知
+    HAND_JUMP_DIALOGUE_SPEAKING_NOTIFY, // 跳转到对话说话界面通知
     MAX_NUM_HANDLER, 
 } UiServiceMsgId;
 
index f074316..4b6c8c9 100644 (file)
@@ -246,6 +246,8 @@ namespace OHOS
         
         // 处理对话响应消息的finished标志
         void HandleDialogueResponseFinished(bool finished);
+        // 处理跳转到对话说话界面
+        void HandleJumpDialogueSpeaking();
         // 减低视频帧率
         void LowFrequence();
         // 恢复视频帧率
index 033cb90..8dac21c 100644 (file)
@@ -27,7 +27,6 @@
  #include <sys/time.h>
  #include <service/graphic_service.h>
 #include "custom_utils.h"
-#include <string.h>
 #include "bluetooth/Ln_Bluetooth_apiC.h"
 #include <algorithm>
 #include <ctime>
@@ -54,6 +53,7 @@
 #include "ConfigModelC.h"
 #include "ConfigModel.h"
 #include "cmsis_os2.h"
+#include "los_task.h"
 #include "custom_runtime.h"
 #include "ln_api_interface.h"
 #ifdef __cplusplus
@@ -61,6 +61,8 @@ extern "C" {
 #endif
 #include "imsl_vad.h"
 #include "dmp_api.h"
+#include <audio_service.h>
+#include <audio_base_type.h>
 #ifdef __cplusplus
 }
 #endif
@@ -2968,7 +2970,44 @@ extern "C" {
             m_dialogueModeFinished = true;
         }
     }
-
+    
+    void ThunderBirdModel::HandleJumpDialogueSpeaking()
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleJumpDialogueSpeaking");
+        
+        // 1. 停止其他音频服务,避免冲突
+        ln_audio_simple_stop();
+        AI_ForceInterrupt();
+        do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_AUDIO_DEINIT, NULL, 0);
+        
+        // 2. 设置常亮屏
+        ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON);
+        
+        // 3. 跳转到对话说话界面
+        if (ThunderBirdMainView::GetInstance()) {
+            int currentView = ThunderBirdMainView::GetInstance()->GetCurrentView();
+            ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW, ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING);
+        }
+        
+        int32_t uiVolume = get_ui_volume();
+        if (uiVolume <= 0 || uiVolume > 100) {
+            uiVolume = 50; // 默认音量50%
+        }
+        AudioServiceSetVolume(AUDIO_STREAM_ALARM_CLOCK, uiVolume);
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleJumpDialogueSpeaking: Set ALARM_CLOCK volume to %d%%", uiVolume);
+        
+        // 5. 循环播放 FactoryMode.mp3(使用 ln_audio_simple_play_loop,支持循环播放,无需线程)
+        const char *factory_mode_file = "/user/res/music/FactoryMode.mp3";
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleJumpDialogueSpeaking: Playing file: %s (will loop)", factory_mode_file);
+        
+        // 使用 ln_audio_simple_play_loop 直接循环播放,无需线程
+        int ret = ln_audio_simple_play_loop(factory_mode_file, true);
+        if (ret != 0) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleJumpDialogueSpeaking: Failed to play file: %s, ret=%d", factory_mode_file, ret);
+        } else {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleJumpDialogueSpeaking: Successfully started loop playback");
+        }
+    }
     void ThunderBirdModel::HandleBluetoothConnect(const char *bluetoothAddress)
     {
         auto* mainView = ThunderBirdMainView::GetInstance();
index 99210d4..f1d626d 100644 (file)
@@ -119,6 +119,7 @@ static void HandDialogueResponseFinishedNotify(Request *request);
 static void HandVadInitializedNotify(Request *request);
 static void HandBluetoothConnectNotify(Request *request);
 static void HandBluetoothEarphoneConnectStatusNotify(Request *request);
+static void HandJumpDialogueSpeakingNotify(Request *request);
 
 // 消息处理程序项数组(每个消息类型对应一个处理函数,函数名以 Handle 开头)
 MsgHandlerEntry msgHandlers[] = {
@@ -150,6 +151,7 @@ MsgHandlerEntry msgHandlers[] = {
     {HAND_VAD_INITIALIZED_NOTIFY,HandVadInitializedNotify},
     {HAND_BLUETOOTH_CONNECT_NOTIFY,HandBluetoothConnectNotify},
     {HAND_BLUETOOTH_EARPHONE_CONNECT_STATUS_NOTIFY,HandBluetoothEarphoneConnectStatusNotify},
+    {HAND_JUMP_DIALOGUE_SPEAKING_NOTIFY,HandJumpDialogueSpeakingNotify},
 };
 /* -------------------------------------------------------------------------- */
 void ScreenTurnOn(int32_t timeout)
@@ -923,6 +925,14 @@ void HandBluetoothEarphoneConnectStatusNotify(Request *request)
                          OHOS::ThunderBirdModel::GetInstance(), connectStatus));
     }
 }
+
+// 跳转到对话说话界面通知
+void HandJumpDialogueSpeakingNotify(Request *request)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandJumpDialogueSpeakingNotify msg_id = %d", request->msgId);
+    GraphicService::GetInstance()->PostGraphicEvent(
+        std::bind(&OHOS::ThunderBirdModel::HandleJumpDialogueSpeaking,OHOS::ThunderBirdModel::GetInstance()));
+}
 /* -------------------------------------------------------------------------- */
 #ifdef __cplusplus
 }
index 09ecff6..a5dbce8 100644 (file)
@@ -11,6 +11,7 @@
 #include "errcode.h"
 #include "ln_api.h"
 #include "ln_api_interface.h"
+#include "ln_audio_simple.h"
 #include "cJSON.h"
 #include "broadcast_feature.h"
 #include "bts_br_gap.h"
@@ -1931,6 +1932,26 @@ static uint32_t ln_ws_set_log_level_at(uint8_t *para, uint32_t paraLen, char *st
     return ERRCODE_SUCC;
 }
 
+/* AT^LN_STRESS_TEST_DIALOGUE - 压测模式:跳转到对话说话界面,常亮屏且循环播放FactoryMode.mp3 */
+static uint32_t ln_stress_test_dialogue_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+    LN_UNUSED(para);
+    LN_UNUSED(paraLen);
+    LN_UNUSED(strCommonCmd);
+    
+    printf("[LN][STRESS_TEST_DIALOGUE] Starting stress test mode: jump to dialogue speaking view, screen always on and loop play FactoryMode.mp3\n");
+    
+    // 发送跳转到对话说话界面的通知
+    push_jump_dialogue_speaking_notification();
+    
+    printf("[LN][STRESS_TEST_DIALOGUE] Stress test mode enabled:\n");
+    printf("  - Jump to THUNDERBIRD_DIALOGUEVIEW_SPEAKING\n");
+    printf("  - Screen always on enabled\n");
+    printf("  - Loop playback: /user/res/music/FactoryMode.mp3\n");
+    
+    return ERRCODE_SUCC;
+}
+
 static const at_cmd_table_t g_ln_api_cmd[] = {
     /* ---------------------------------- 雷鸟API --------------------------------- */
     {(char *)"AT^LN_GET_TOKEN", ln_get_device_token_at, (char *)"获取雷鸟设备Token: AT^LN_GET_TOKEN[=deviceId,deviceIccid,deviceModel,deviceVersion]"},
@@ -2014,8 +2035,8 @@ static const at_cmd_table_t g_ln_api_cmd[] = {
     {(char *)"AT^LN_DEBUG_POPUP", ln_debug_popup_at, (char *)"debug界面弹窗提示: AT^LN_DEBUG_POPUP[=message]"},
     
     //帧率控制
-    {(char *)"AT^LN_SET_FPS", ln_set_fps_at, (char *)"设置帧率: AT^LN_SET_FPS=<fps_value>"},
-    {(char *)"AT^LN_GET_FPS", ln_get_fps_at, (char *)"获取当前帧率: AT^LN_GET_FPS"},
+    // {(char *)"AT^LN_SET_FPS", ln_set_fps_at, (char *)"设置帧率: AT^LN_SET_FPS=<fps_value>"},
+    // {(char *)"AT^LN_GET_FPS", ln_get_fps_at, (char *)"获取当前帧率: AT^LN_GET_FPS"},
     
     //WS状态和网络参数显示
     {(char *)"AT^LN_SHOW_WS_NET", ln_show_ws_net_at, (char *)"显示WS连接状态和网络参数: AT^LN_SHOW_WS_NET[=-p x,y]"},
@@ -2031,7 +2052,9 @@ static const at_cmd_table_t g_ln_api_cmd[] = {
     {(char *)"AT^LN_BT_DISCONNECT", ln_bt_disconnect_at, (char *)"断开蓝牙设备: AT^LN_BT_DISCONNECT=AA:BB:CC:DD:EE:FF"},
 
     //WebSocket日志等级设置
-    {(char *)"AT^LN_WS_LOG_LEVEL", ln_ws_set_log_level_at, (char *)"设置WebSocket日志等级: AT^LN_WS_LOG_LEVEL=0-3"},
+    {(char *)"AT^LN_WS_LOG_LEVEL", ln_ws_set_log_level_at, (char *)"设置WebSocket日志等级: AT^LN_WS_LOG_LEVEL=0-3"},  
+     //压测相关
+    {(char *)"AT^LN_STRESS_TEST_DIALOGUE", ln_stress_test_dialogue_at, (char *)"压测模式:跳转到对话说话界面,常亮屏且循环播放FactoryMode.mp3: AT^LN_STRESS_TEST_DIALOGUE"},
 };
 
 
index 1e9845c..2593e44 100644 (file)
@@ -325,6 +325,13 @@ void push_dialogue_response_finished_notification(bool finished)
     SendMsgToUIService(HAND_DIALOGUE_RESPONSE_FINISHED_NOTIFY, 0, &finished, sizeof(finished));
 }
 
+//通知跳转到对话说话界面
+void push_jump_dialogue_speaking_notification(void)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[JUMP_DIALOGUE_SPEAKING] Jump to dialogue speaking view");
+    SendMsgToUIService(HAND_JUMP_DIALOGUE_SPEAKING_NOTIFY, 0, NULL, 0);
+}
+
 //通知VAD初始化完成
 void push_vad_initialized_notification(void)
 {
index 2d58254..88f6d19 100644 (file)
@@ -119,6 +119,8 @@ void push_upgrade_description_notification(const char *description);
 void push_story_response_finished_notification(bool finished);
 //通知对话响应finished
 void push_dialogue_response_finished_notification(bool finished);
+//通知跳转到对话说话界面
+void push_jump_dialogue_speaking_notification(void);
 //通知VAD初始化完成
 void push_vad_initialized_notification(void);
 //通知进行蓝牙耳机连接操作
index 49da1ba..124bbb2 100644 (file)
@@ -284,6 +284,82 @@ int ln_audio_simple_play(const char *file_path)
     return 0;
 }
 
+int ln_audio_simple_play_loop(const char *file_path, bool loop)
+{
+    if (!file_path || file_path[0] == '\0')
+    {
+        printf("[LN_AUDIO_SIMPLE] invalid file path\n");
+        return -1;
+    }
+
+    if (!AudioInitOnce())
+        return -2;
+
+    // 设置播放器回调
+    g_simple.player->SetPlayerCallback(g_player_callback);
+
+    // 设置音频源
+    g_simple.source = std::make_shared<Source>(file_path, g_simple.header);
+    if (!g_simple.source)
+    {
+        printf("[LN_AUDIO_SIMPLE] create Source failed\n");
+        return -3;
+    }
+
+    int32_t ret;
+    ret = g_simple.player->SetSource(*g_simple.source);
+    if (ret != 0)
+    {
+        printf("[LN_AUDIO_SIMPLE] SetSource failed: %d\n", ret);
+        g_simple.player->Reset();
+        return -4;
+    }
+
+    // 设置循环播放
+    g_simple.player->EnableSingleLooping(loop);
+    g_simple.player->SetAudioStreamType(AUDIO_STREAM_ALARM_CLOCK);
+
+    // 在 Prepare 之前激活音频中断,因为 Prepare 时会创建音频流,需要有效的音频中断会话
+    if (!EnsureAudioInterrupt())
+    {
+        g_simple.player->Reset();
+        return -6;
+    }
+
+    ret = g_simple.player->Prepare();
+    if (ret != 0)
+    {
+        printf("[LN_AUDIO_SIMPLE] Prepare failed: %d\n", ret);
+        g_simple.player->Reset();
+        ClearAudioInterrupt();
+        return -5;
+    }
+
+    ret = g_simple.player->SetAudioSessionId(g_simple.sessionId);
+    if (ret != 0)
+    {
+        printf("[LN_AUDIO_SIMPLE] SetAudioSessionId failed: %d\n", ret);
+        g_simple.player->Reset();
+        ClearAudioInterrupt();
+        return -7;
+    }
+
+    ret = g_simple.player->Play();
+    if (ret != 0)
+    {
+        printf("[LN_AUDIO_SIMPLE] Play failed: %d\n", ret);
+        g_simple.player->Stop();
+        g_simple.player->Reset();
+        ClearAudioInterrupt();
+        return -8;
+    }
+
+    g_simple.is_playing = true;
+    g_simple.is_paused = false;
+    printf("[LN_AUDIO_SIMPLE] started: %s (loop=%s)\n", file_path, loop ? "true" : "false");
+    return 0;
+}
+
 int ln_audio_simple_stop(void)
 {
     if (!g_simple.player)
index 70eaf9c..61f5783 100644 (file)
@@ -29,6 +29,17 @@ extern "C" {
  */
 int ln_audio_simple_play(const char *file_path);
 
+/*
+ * 播放本地音频文件(支持循环播放)
+ * 参数:
+ *   file_path - 音频文件的绝对路径
+ *   loop - 是否循环播放
+ * 返回:
+ *   0  成功启动播放(异步)
+ *  <0  失败
+ */
+int ln_audio_simple_play_loop(const char *file_path, bool loop);
+
 /*
  * 主动停止播放(同步停止,确保资源释放)
  * 返回:0 成功,<0 失败