272:对接压力测试接口添加测试逻辑
authorluozheng <1732036298@qq.com>
Mon, 17 Nov 2025 02:52:33 +0000 (10:52 +0800)
committerluozheng <1732036298@qq.com>
Mon, 17 Nov 2025 02:52:33 +0000 (10:52 +0800)
code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/include/stressTestModel.h
code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/src/stressTestModel.cpp
code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/src/stressTestingView.cpp

index eb41966..ac018e7 100644 (file)
@@ -42,6 +42,12 @@ namespace OHOS
         // 定时器相关
         void StressTest_StartTimer(uint32_t interval = 1 * 1000, int type = 0);
         void StressTest_StopTimer(void);
+        
+        // 压力数据处理(参考UpHeartdata)
+        void UpStressData(uint8_t stress);
+        
+        // 设置佩戴状态(参考SetWearStatus)
+        void SetWearStatus(void);
 
     private:
         StressTestModel();
index 5bd7020..9cbb1b7 100644 (file)
@@ -8,8 +8,13 @@
 #include "custom_utils.h"
 #include <vibrator_service.h>
 #include <stdio.h>
-#include <stdlib.h> // 包含 rand()、srand() 函数
-#include <time.h>   // 包含 time() 函数,用于生成随机种子
+#include <stdlib.h>
+#include <time.h>
+
+#ifdef SUPPORT_PPG_SERVICE
+#include "ppg_service.h"
+#include "ppg_hal.h"
+#endif
 
 namespace OHOS
 {
@@ -159,111 +164,180 @@ namespace OHOS
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::HandleResultValue: %dms", currentResultValue);
     }
 
-    static uint16_t StressAlgo_FetchOneSecondData(void)
-    {
-        // 初始化随机种子(仅需初始化一次,放在函数外更高效)
-        static int initialized = 0;
-        if (!initialized)
-        {
-            srand((unsigned int)time(NULL)); // 以当前时间作为种子,确保每次运行结果不同
-            initialized = 1;
-        }
+// 压力测量相关常量定义(参考心率测量的定义)
+#define MAX_VALID_STRESS_COUNT 40    // 最大有效数据个数(60秒内至少需要40个有效数据)
+#define MAX_DISVALID_STRESS_COUNT 15 // 最大无效数据个数(连续15次无效则停止)
+#define MAX_UNWEAR_COUNT 2           // 最大未佩戴次数
+#define STRESS_TEST_DURATION_SEC 120  // 压力测试持续时间(秒)
 
-        // rand() 生成 [0, RAND_MAX] 的随机整数,取模 101 后得到 [0, 100]
-        return (uint16_t)(rand() % 101);
-    }
+    // 压力测量状态变量
+    static uint16_t valid_counter_ = 0;     // 有效数据计数器
+    static uint16_t disvalid_counter_ = 0;  // 无效数据计数器
+    static uint16_t unwear_counter_ = 0;    // 未佩戴计数器
+    static uint16_t test_duration_sec_ = 0; // 测试持续时间(秒)
+    static uint16_t stress_value_ = 0;      // 当前压力值
+    static uint16_t ringBuffer[60]{0};      // 压力测试结果环形缓冲区
+    static uint16_t ringBufferIndex = 0;    // 环形缓冲区索引
 
     GraphicTimer *g_stressTestTimer = nullptr;
-    static int g_stressTestTimerCount = 0;  // 压力测试定时器计数
-    static int g_invalidConsecutiveSec = 0; // 无效连续次数计数
-    static uint8_t validCount{0};           // 有效数据个数
-    static uint16_t ringBuffer[60]{0};      // 压力测试结果环形缓冲区
 
-    static void resetStressTestTimerData(void)
+    // 重置压力测试数据
+    static void resetStressTestData(void)
     {
-        g_stressTestTimerCount = 0;
-        g_invalidConsecutiveSec = 0;
-        validCount = 0;
+        valid_counter_ = 0;
+        disvalid_counter_ = 0;
+        unwear_counter_ = 0;
+        test_duration_sec_ = 0;
+        stress_value_ = 0;
+        ringBufferIndex = 0;
         for (int i = 0; i < 60; i++)
         {
             ringBuffer[i] = 0;
         }
     }
 
-    static void StressTestTimerCallbackProc(void *data)
+    // 处理压力数据(参考UpHeartdata函数)
+    void StressTestModel::UpStressData(uint8_t stress)
     {
-        (void)data;
-        //秒
-        g_stressTestTimerCount++;
-        // 模拟出压力测试值
-        uint16_t rawValueMs = StressAlgo_FetchOneSecondData();
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "当前秒数: %d, 压力测试值: %dms", g_stressTestTimerCount, rawValueMs);
-
-        bool isValueRange = (rawValueMs >= 0 && rawValueMs <= 100);
-        if (!isValueRange)
+        stress_value_ = stress;
+        test_duration_sec_++;
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "测试时长:%d", test_duration_sec_);
+        if(test_duration_sec_ < 40)
         {
-            g_invalidConsecutiveSec++;
+            return;//至少要30s后才能出值
+        }
+
+        // 更新压力值和计数器
+        if (stress_value_ > 0 && stress_value_ <= 100)
+        {
+            // 有效数据:存储到环形缓冲区
+            ringBuffer[ringBufferIndex % 60] = stress_value_;
+            ringBufferIndex++;
+            valid_counter_++;      // 增加有效计数器
+            disvalid_counter_ = 0; // 清空无效计数器
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "压力测试有效数据: %d, 有效计数: %d, 测试时长: %d秒",
+                          stress_value_, valid_counter_, test_duration_sec_);
         }
         else
         {
-            g_invalidConsecutiveSec = 0;
-            ringBuffer[validCount % 60] = rawValueMs;
-            validCount++;
+            // 无效数据
+            disvalid_counter_++; // 增加无效计数器
+            valid_counter_ = 0;  // 清零有效计数器(连续有效才计数)
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "压力测试无效数据: %d, 无效计数: %d, 测试时长: %d秒",
+                          stress_value_, disvalid_counter_, test_duration_sec_);
         }
 
-        /* 无效连续次数超过10次,停止压力测试 */
-        if (g_invalidConsecutiveSec >= 10)
+        // 检查无效计数器是否达标
+        if (disvalid_counter_ >= MAX_DISVALID_STRESS_COUNT)
         {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::StressTestTimerCallbackProc: 无效连续次数超过10次,停止压力测试");
-            StressTestModel::GetInstance().StressTest_StopTimer();
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "压力测试: 无效数据过多 disvalid_counter:%d", disvalid_counter_);
+            StressTestModel::GetInstance().SetCurrentFailType(StressTestModel::FAIL_TYPE_INVALID_DATA);
+            StressTest_StopTimer();
             // 震动提醒
             custom_VibratorFunc_int(0);
+            // 切换到失败页面
             if (StressTestPresenter::GetInstance())
             {
-                StressTestPresenter::GetInstance()->ChangeViewOperation(StressTestModel::GetInstance().GetCurrentView(), STRESSTESTFAILVIEW);
+                StressTestPresenter::GetInstance()->ChangeViewOperation(
+                    StressTestModel::GetInstance().GetCurrentView(), STRESSTESTFAILVIEW);
             }
             return;
         }
-        // 完成判定
-        if (g_stressTestTimerCount >= 60 && validCount >= 40)
+
+        if (ringBufferIndex >= MAX_VALID_STRESS_COUNT)
         {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::StressTestTimerCallbackProc: 完成判定,计算最终结果");
             // 计算最终结果,有效值的均值
             uint16_t sum = 0;
-            for (int i = 0; i < validCount; i++)
+            uint16_t count = (ringBufferIndex < 60) ? ringBufferIndex : 60;
+            for (int i = 0; i < count; i++)
             {
                 sum += ringBuffer[i];
             }
-            uint16_t finalMs = sum / validCount;
+            uint16_t finalMs = sum / count;
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "压力测试完成: 最终结果 %dms, 有效数据个数: %d", finalMs, count);
+            // 停止压力测试
+            StressTest_StopTimer();
+
             StressTestModel &m = StressTestModel::GetInstance();
             m.HandleResultValue(finalMs); // 分档上报
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::StressTestTimerCallbackProc: 最终结果: %dms", finalMs);
+
             // 切换到结果页面
             if (StressTestPresenter::GetInstance())
             {
-                StressTestPresenter::GetInstance()->ChangeViewOperation(StressTestModel::GetInstance().GetCurrentView(), STRESSTESTRESULTVIEW);
+                StressTestPresenter::GetInstance()->ChangeViewOperation(
+                    StressTestModel::GetInstance().GetCurrentView(), STRESSTESTRESULTVIEW);
             }
-            //停止压力测试定时器
-            StressTestModel::GetInstance().StressTest_StopTimer();
         }
-        else if (g_stressTestTimerCount >= 60 && validCount < 40)
+        // 检查是否达到测试时长且有效数据足够
+        if ((test_duration_sec_ >= STRESS_TEST_DURATION_SEC) && ringBufferIndex < MAX_VALID_STRESS_COUNT)
         {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::StressTestTimerCallbackProc: 完成判定,计算最终结果");
-            //停止压力测试定时器
-            StressTestModel::GetInstance().StressTest_StopTimer();
+            // 有效数据不足
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "压力测试: 有效数据不足 ringBufferIndex:%d", ringBufferIndex);
+            StressTestModel::GetInstance().SetCurrentFailType(StressTestModel::FAIL_TYPE_INVALID_DATA);
             // 震动提醒
             custom_VibratorFunc_int(0);
-            // 切换到结果页面
+            // 停止压力测试
+            StressTest_StopTimer();
+            // 切换到失败页面
             if (StressTestPresenter::GetInstance())
             {
-                StressTestPresenter::GetInstance()->ChangeViewOperation(StressTestModel::GetInstance().GetCurrentView(), STRESSTESTFAILVIEW);
+                StressTestPresenter::GetInstance()->ChangeViewOperation(
+                    StressTestModel::GetInstance().GetCurrentView(), STRESSTESTFAILVIEW);
             }
+            return;
         }
     }
 
-    static void StressTestTimerCallback(void *data)
+    // 设置佩戴状态(参考SetWearStatus函数)
+    void StressTestModel::SetWearStatus(void)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "压力测试: 未佩戴状态 unwear_counter_:%d", unwear_counter_);
+        unwear_counter_++;
+
+        if (unwear_counter_ > MAX_UNWEAR_COUNT)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "压力测试: 未佩戴次数过多,停止测试");
+            StressTestModel::GetInstance().SetCurrentFailType(StressTestModel::FAIL_TYPE_NOT_WORN);
+            StressTest_StopTimer();
+            // 震动提醒
+            custom_VibratorFunc_int(0);
+            // 切换到失败页面
+            if (StressTestPresenter::GetInstance())
+            {
+                StressTestPresenter::GetInstance()->ChangeViewOperation(
+                    StressTestModel::GetInstance().GetCurrentView(), STRESSTESTFAILVIEW);
+            }
+        }
+    }
+
+    // 压力数据回调处理函数(参考heart_data_callbackProc)
+    static void stress_data_callbackProc(void *data)
+    {
+        // 更新佩戴状态
+        uint8_t wear = 1;
+#ifdef SUPPORT_PPG_SERVICE
+        wear = ppg_get_wear_status();
+#endif
+        if (wear == 0)
+        {
+            OHOS::StressTestModel::GetInstance().SetWearStatus();
+        }
+
+        // 更新压力值
+        uint8_t hrv = 0;
+#ifdef SUPPORT_PPG_SERVICE
+        hrv = ppg_get_hrv();
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "stress_data_callbackProc: hrv = %d, wear = %d", hrv, wear);
+#endif
+
+        OHOS::StressTestModel::GetInstance().UpStressData(hrv);
+    }
+
+    // 定时器回调函数(切换到图形线程)
+    static void stress_data_timer_callback(void *data)
     {
-        GraphicService::GetInstance()->PostGraphicEvent(std::bind(StressTestTimerCallbackProc, data));
+        GraphicService::GetInstance()->PostGraphicEvent(
+            std::bind(stress_data_callbackProc, data));
     }
 
     // 开启压力测试定时器
@@ -272,7 +346,7 @@ namespace OHOS
         uint32_t tick = GetOSTick(interval);
         if (g_stressTestTimer == nullptr)
         {
-            g_stressTestTimer = new GraphicTimer(tick, StressTestTimerCallback, nullptr, true);
+            g_stressTestTimer = new GraphicTimer(tick, stress_data_timer_callback, nullptr, true);
             if (g_stressTestTimer == nullptr)
             {
                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::StressTest_StartTimer new GraphicTime failed!!");
@@ -297,6 +371,9 @@ namespace OHOS
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::StressTest_StartTimer: 压力测试定时器启动成功");
             // 常亮屏幕
             ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON);
+            #ifdef SUPPORT_PPG_SERVICE
+            ppg_hrv_start();
+            #endif
         }
     }
 
@@ -312,7 +389,10 @@ namespace OHOS
             // 取消常亮屏
             ScreenAlwaysOnCtr(CANCEL_SCREEN_ALWAYS_ON);
             // 重置压力测试定时器数据
-            resetStressTestTimerData();
+            resetStressTestData();
+            #ifdef SUPPORT_PPG_SERVICE
+            ppg_hrv_stop();
+            #endif
         }
     }
 }
index 884ea64..d7ae977 100644 (file)
@@ -7,7 +7,7 @@ namespace OHOS
     static constexpr int STRESS_TESTING_IMAGE_ANIMATOR_VIEW_Y = 60;
     static constexpr int STRESS_TESTING_IMAGE_ANIMATOR_VIEW_W = 260;
     static constexpr int STRESS_TESTING_IMAGE_ANIMATOR_VIEW_H = 260;
-    static constexpr int STRESS_TESTING_IMAGE_ANIMATOR_DELAY = 75; // 图片更新间隔
+    static constexpr int STRESS_TESTING_IMAGE_ANIMATOR_DELAY = 100; // 图片更新间隔
 
     const char *stress_testing_image_path_array[] = {
         "/user/res/stress/stress_gif/bg1_CS6.bin",