修复哄睡一直准备故事bug,并增加超时处理
authorxue <2144439972@qq.com>
Mon, 1 Dec 2025 03:24:28 +0000 (11:24 +0800)
committerxue <2144439972@qq.com>
Mon, 1 Dec 2025 03:24:28 +0000 (11:24 +0800)
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdLullabyView.h
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdModel.h
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdPresenter.h
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdLullabyView.cpp
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdPresenter.cpp

index fcb3662..7ddaf5c 100644 (file)
@@ -44,6 +44,7 @@ namespace OHOS
         ImageAnimatorInfo listenImageInfo[TB_LISTEN_FRAMES];
         const char **listenPathsArray{nullptr};
         void UpdateLullabyText(const char *text);
+        std::string GetCurrentText() const;  // 获取当前文本
 
     private:
         UIViewGroup *group{nullptr};
index b2505ae..0bc416f 100644 (file)
@@ -40,6 +40,10 @@ namespace OHOS
         void StartCountUpTimer(uint32_t targetSeconds);
         void StopCountUpTimer(void);
         int GetCountUpValue() const;
+        
+        // 故事模式超时定时器(1分钟无文本切换则退出)
+        void StartStoryModeTimeoutTimer(void);
+        void StopStoryModeTimeoutTimer(void);
 
         // 开机操作函数
         int StartBootOperation();
@@ -230,6 +234,8 @@ namespace OHOS
         
         // 处理故事响应消息的finished标志
         void HandleStoryResponseFinished(bool finished);
+        // 故事模式超时处理函数
+        void HandleStoryModeTimeout(void);
         
         // 处理蓝牙耳机连接通知
         void HandleBluetoothConnect(const char *bluetoothAddress);
@@ -382,6 +388,7 @@ namespace OHOS
         
         // 故事模式相关标志
         bool m_storyModeFinished = false;    // 故事模式是否已finished(收到finished=true)
+        void* m_storyModeTimeoutTimer;        // 故事模式超时定时器(1分钟无文本切换则退出)
         
         // 对话模式相关标志
         bool m_dialogueModeFinished = false; // 对话模式是否已finished(收到finished=true)
index 48f4d1e..49ab75d 100644 (file)
@@ -47,6 +47,9 @@ namespace OHOS
          void RegisterFuncKeyLongPressEvent(void);
          void HandleFuncKeyLongPress(void);
          
+         // 重置哄睡录音标志位
+         void ResetLullabyRecording(void);
+         
     private:
         bool OnKeyAct(UIView &view, const KeyEvent &event) override; // 增加按键事件
         bool X_DRAG_FLAG{false};
index 17aa907..975f52a 100644 (file)
@@ -307,6 +307,10 @@ namespace OHOS
         case THUNDERBIRD_LULLABYVIEW_3:
         {
             listenAnimator->Stop();
+            // 重置哄睡录音标志位,确保进入界面时状态正确
+            if (ThunderBirdPresenter::GetInstance()) {
+                ThunderBirdPresenter::GetInstance()->ResetLullabyRecording();
+            }
             // ln_ws_start_audio_chat(LN_AUDIO_CHAT_CHOOSE_STORY_REQUEST);
             ThunderBirdMainView::GetInstance()->OpenBackGround();
             if (TextLabel)
@@ -365,6 +369,9 @@ namespace OHOS
             ThunderBirdModel::GetInstance()->LowFrequence();//减低视频帧率
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdLullabyView::Show: THUNDERBIRD_LULLABYVIEW_4");
             
+            // 启动故事模式超时定时器(1分钟无文本切换则退出)
+            ThunderBirdModel::GetInstance()->StartStoryModeTimeoutTimer();
+            
             // 进入故事模式时关闭VAD
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "进入故事模式,关闭VAD");
             int vad_ret = ln_ws_disable_vad_server();
@@ -502,10 +509,29 @@ namespace OHOS
             return;
         }
         
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdLullabyView::UpdateLullabyText: 更新故事文字: %s", text ? text : "null");
+        // 获取当前文本
+        std::string currentText = TextLabel->GetText();
+        std::string newText = text ? text : "";
+        
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdLullabyView::UpdateLullabyText: 更新故事文字: %s (原文本: %s)", newText.c_str(), currentText.c_str());
+        
+        // 如果文本从 "正在准备故事..." 切换到其他文本,停止故事模式超时定时器
+        if (currentText == "正在准备故事..." && newText != "正在准备故事..." && !newText.empty()) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdLullabyView::UpdateLullabyText: 文本已切换,停止故事模式超时定时器");
+            ThunderBirdModel::GetInstance()->StopStoryModeTimeoutTimer();
+        }
+        
         // 设置文本
         TextLabel->SetText(text);
     }
+    
+    std::string ThunderBirdLullabyView::GetCurrentText() const
+    {
+        if (TextLabel) {
+            return TextLabel->GetText();
+        }
+        return "";
+    }
 }
 
 
index 473f1ee..e97845f 100644 (file)
@@ -158,7 +158,8 @@ extern "C" {
                                            m_simStatus(0), m_cat1PowerStatus(0), m_signalStrength(0),
                                            m_networkStatus(0), m_networkType(0),
                                            m_hasNetwork(false), m_networkStatusChanged(false),
-                                           m_rsrq(255), m_rsrp(255)
+                                           m_rsrq(255), m_rsrp(255),
+                                           m_storyModeTimeoutTimer(nullptr)
      {
          //设置屏幕亮度为20
         //  cm_set_brightness(20);
@@ -209,6 +210,7 @@ extern "C" {
          StopTimeDisplayTimer();
          StopOtaCountdown();
          StopCountUpTimer();
+         StopStoryModeTimeoutTimer();
          //StopReminderHideTimer();
          
          // 停止录音
@@ -368,6 +370,84 @@ extern "C" {
      {
          return m_countUpValue;
      }
+     
+     // 故事模式超时定时器回调函数前向声明
+     static void StoryModeTimeoutTimerCallback(uint8_t data);
+     
+     // ---------------------- 故事模式超时定时器 ----------------------
+     void ThunderBirdModel::StartStoryModeTimeoutTimer(void)
+     {
+         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StartStoryModeTimeoutTimer: 启动1分钟超时定时器");
+         
+         // 如果定时器已存在,先停止
+         if (m_storyModeTimeoutTimer != nullptr) {
+             StopStoryModeTimeoutTimer();
+         }
+         
+         // 创建一次性定时器(1分钟 = 60000毫秒)
+         m_storyModeTimeoutTimer = osTimerNew((osTimerFunc_t)StoryModeTimeoutTimerCallback, osTimerOnce, nullptr, nullptr);
+         if (m_storyModeTimeoutTimer == nullptr) {
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create story mode timeout timer");
+             return;
+         }
+         
+         // 启动定时器(1分钟 = 60000毫秒)
+         osStatus_t ret = osTimerStart(m_storyModeTimeoutTimer, 60000);
+         if (ret != osOK) {
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to start story mode timeout timer, ret=%d", ret);
+             osTimerDelete(m_storyModeTimeoutTimer);
+             m_storyModeTimeoutTimer = nullptr;
+         } else {
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Story mode timeout timer started: 60 seconds");
+         }
+     }
+     
+     void ThunderBirdModel::StopStoryModeTimeoutTimer(void)
+     {
+         if (m_storyModeTimeoutTimer != nullptr) {
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StopStoryModeTimeoutTimer: 停止故事模式超时定时器");
+             osTimerStop(m_storyModeTimeoutTimer);
+             osTimerDelete(m_storyModeTimeoutTimer);
+             m_storyModeTimeoutTimer = nullptr;
+         }
+     }
+     
+     // 故事模式超时处理函数
+     void ThunderBirdModel::HandleStoryModeTimeout(void)
+     {
+         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HandleStoryModeTimeout: 1分钟未切换文本,退出故事模式");
+         
+         // 检查当前是否还在故事模式
+         ThunderBirdMainView *view = ThunderBirdMainView::GetInstance();
+         if (view) {
+             int16_t currentView = view->GetCurrentView();
+             int16_t currentSubView = view->GetCurrentSubView();
+             
+             if (currentView == THUNDERBIRD_LULLABYVIEW && 
+                 currentSubView == ThunderBirdLullabyView::THUNDERBIRD_LULLABYVIEW_4) {
+                 // 检查文本是否还是 "正在准备故事..."
+                 ThunderBirdLullabyView *lullabyView = ThunderBirdLullabyView::GetInstance();
+                 if (lullabyView) {
+                     std::string currentText = lullabyView->GetCurrentText();
+                     if (currentText == "正在准备故事...") {
+                         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HandleStoryModeTimeout: 文本仍为'正在准备故事...',退出故事模式");
+                         // 停止定时器
+                         StopStoryModeTimeoutTimer();
+                         // 退出故事模式
+                         HandleSleepModeEnd();
+                         return;
+                     } else {
+                         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HandleStoryModeTimeout: 文本已切换为'%s',不退出故事模式", currentText.c_str());
+                         // 文本已切换,停止定时器
+                         StopStoryModeTimeoutTimer();
+                     }
+                 }
+             } else {
+                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HandleStoryModeTimeout: 当前不在故事模式,停止定时器");
+                 StopStoryModeTimeoutTimer();
+             }
+         }
+     }
 
      //传入OTA的界面状态,以返回原任务
     int16_t ThunderBirdModel::GetCurrentView() const
@@ -1380,6 +1460,15 @@ extern "C" {
              }));
      }
      
+     // 故事模式超时定时器回调函数(需要在使用前声明)
+     static void StoryModeTimeoutTimerCallback(uint8_t data)
+     {
+         GraphicService::GetInstance()->PostGraphicEvent(
+             std::bind([]() {
+                 ThunderBirdModel::GetInstance()->HandleStoryModeTimeout();
+             }));
+     }
+     
     /**
      * @brief 启动时间显示定时器
      * @param interval 定时器间隔,单位毫秒,默认1000ms
@@ -2598,6 +2687,8 @@ extern "C" {
     void ThunderBirdModel::HandleSleepModeEnd()
     {
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleSleepModeEnd");
+        // 停止故事模式超时定时器
+        StopStoryModeTimeoutTimer();
         // 重置故事模式finished标志
         m_storyModeFinished = false;
         
index 796c142..8021fac 100644 (file)
@@ -515,6 +515,15 @@ namespace OHOS
         }
     }
 
+    /**
+     * @brief 重置哄睡录音标志位
+     */
+    void ThunderBirdPresenter::ResetLullabyRecording(void)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdPresenter::ResetLullabyRecording: 重置哄睡录音标志位");
+        isLullabyRecording = false;
+    }
+
         /**
      * @brief 处理哄睡功能
      */
@@ -522,13 +531,29 @@ namespace OHOS
      {
          if (currentView == THUNDERBIRD_LULLABYVIEW && 
              currentSubView == ThunderBirdLullabyView::THUNDERBIRD_LULLABYVIEW_3) {
+                // 检查音频聊天是否实际处于活动状态,同步标志位
+                const char* chatId = ln_ws_get_current_chat_id();
+                bool audioChatActive = (chatId != NULL);
+                
+                // 如果标志位与实际状态不一致,同步标志位
+                if (isLullabyRecording != audioChatActive) {
+                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HandleLullabyFunction: 标志位状态不一致,同步状态 (isLullabyRecording=%d, audioChatActive=%d)", 
+                                 isLullabyRecording, audioChatActive);
+                    isLullabyRecording = audioChatActive;
+                }
+                
                 if(isLullabyRecording == false)
                 {
                     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始录音");
                     // ThunderBirdModel::GetInstance()->StartRecording();
                     isLullabyRecording = true;
                     ThunderBirdLullabyView::GetInstance()->listenAnimator->Start();
-                    ln_ws_start_audio_chat(LN_AUDIO_CHAT_CHOOSE_STORY_REQUEST);
+                    int ret = ln_ws_start_audio_chat(LN_AUDIO_CHAT_CHOOSE_STORY_REQUEST);
+                    if (ret != 0) {
+                        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HandleLullabyFunction: 启动音频聊天失败 (ret=%d),重置标志位", ret);
+                        isLullabyRecording = false;
+                        ThunderBirdLullabyView::GetInstance()->listenAnimator->Stop();
+                    }
                     return;
                 }
                 else
@@ -536,9 +561,16 @@ namespace OHOS
                     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "结束录音");
                     // 停止录音并发送
                     // ThunderBirdModel::GetInstance()->StopRecording();
-                    ln_ws_end_audio_chat();
-                    isLullabyRecording = false;
-                    ThunderBirdLullabyView::GetInstance()->listenAnimator->Stop();
+                    int ret = ln_ws_end_audio_chat();
+                    if (ret != 0) {
+                        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HandleLullabyFunction: 结束音频聊天失败 (ret=%d),可能没有活动的音频聊天", ret);
+                        // 即使失败也重置标志位,避免状态不一致
+                        isLullabyRecording = false;
+                        ThunderBirdLullabyView::GetInstance()->listenAnimator->Stop();
+                    } else {
+                        isLullabyRecording = false;
+                        ThunderBirdLullabyView::GetInstance()->listenAnimator->Stop();
+                    }
                     //跳转到故事界面
                     ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_LULLABYVIEW, ThunderBirdLullabyView::THUNDERBIRD_LULLABYVIEW_4);
                     return;