优化测量流程 3446/1
authorxue <2144439972@qq.com>
Tue, 9 Jun 2026 04:00:19 +0000 (12:00 +0800)
committerxue <2144439972@qq.com>
Tue, 9 Jun 2026 04:00:19 +0000 (12:00 +0800)
code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/include/BPMainPresenter.h
code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/src/BPCalibratingView.cpp
code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/src/BPMainPresenter.cpp
code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/include/ECGMainPresenter.h
code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/src/ECGMainPresenter.cpp

index 04ae824..9ca6101 100644 (file)
@@ -56,9 +56,15 @@ private:
   void UpdateProgressUi(int percent);
   void CompleteCalibrationFlow(uint8_t sbp, uint8_t dbp);
   void CompleteMeasureFlow(uint8_t sbp, uint8_t dbp);
+  void StartPpgSession(BPProgressMode mode);
+  void StopPpgSession();
+  void SetScreenAlwaysOnForBp(bool enable);
+  bool PollPpgResult();
+  static bool IsValidBpReading(int sbp, int dbp);
   static void ProgressTimerThunk(void *arg);
 
-  static constexpr uint32_t kProgressTickMs = 150U;
+  /** 约 30s 完成(算法需 ~30s ECG 采集) */
+  static constexpr uint32_t kProgressTickMs = 300U;
   static constexpr int kProgressMaxPercent = 100;
 
   GraphicTimer *progressTimer_{nullptr};
@@ -69,6 +75,7 @@ private:
   int16_t stopReturnView_{MAX_BPVIEW};
   bool stopIsMeasure_{false};
   BPProgressMode lastTimeoutMode_{BPProgressMode::None};
+  bool screenAlwaysOnForBp_{false};
 };
 
 } // namespace OHOS
index fd9f8b8..bd606d1 100644 (file)
@@ -19,7 +19,10 @@ static constexpr uint32_t BP_PROGRESS_FG_COLOR_END = 0xff5320E2;
 
 static BPCalibratingView *g_instance = nullptr;
 
-BPCalibratingView::BPCalibratingView() { g_instance = this; }
+BPCalibratingView::BPCalibratingView() {
+  //常亮屏
+  
+   g_instance = this; }
 
 BPCalibratingView::~BPCalibratingView() {
   if (group_ != nullptr) {
@@ -121,7 +124,7 @@ UIViewGroup *BPCalibratingView::InitView() {
   statusLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
 
   percentValue_ = new UILabel();
-  percentValue_->SetPosition(175-44, 179);
+  percentValue_->SetPosition(175-44 + 20, 179);
   percentValue_->Resize(132, 56);
   percentValue_->SetViewId("bp_calib_percent");
   percentValue_->SetText("0");
index 1f8a45a..6904bbd 100644 (file)
 #include <map>
 #include <string>
 
+#ifdef SUPPORT_PPG_SERVICE
+#include "ppg_hal.h"
+#include "ppg_service.h"
+#endif
+
 namespace OHOS {
 
 static BPMainPresenter *g_pBPMainPresenter = nullptr;
@@ -49,6 +54,7 @@ void BPMainPresenter::OnResume(void) {
     int16_t current = mainView->GetCurrentViewId();
     if (current == BP_MEASURING_VIEW || current == BP_CALIBRATING_VIEW) {
       ResumeProgressSession();
+      SetScreenAlwaysOnForBp(true);
     }
   }
 }
@@ -68,6 +74,7 @@ bool BPMainPresenter::NeedsStopConfirm(int16_t viewId) const {
   return viewId == BP_MEASURING_VIEW || viewId == BP_CALIBRATING_VIEW;
 }
 
+/** 请求停止确认 */
 void BPMainPresenter::RequestStopConfirm(int16_t fromView) {
   BPMainView *mainView = BPMainView::GetInstance();
   if (mainView == nullptr) {
@@ -83,6 +90,7 @@ void BPMainPresenter::RequestStopConfirm(int16_t fromView) {
   mainView->ChangeView(fromView, BP_CALIB_STOP_VIEW);
 }
 
+/** 处理滑动返回 */
 bool BPMainPresenter::HandleSwipeBack() {
   BPMainView *mainView = BPMainView::GetInstance();
   if (mainView == nullptr) {
@@ -107,6 +115,7 @@ bool BPMainPresenter::HandleSwipeBack() {
   return true;
 }
 
+/** 进度定时器回调 */
 void BPMainPresenter::ProgressTimerThunk(void *arg) {
   auto *self = static_cast<BPMainPresenter *>(arg);
   if (self == nullptr) {
@@ -115,6 +124,7 @@ void BPMainPresenter::ProgressTimerThunk(void *arg) {
   GraphicService::GetInstance()->PostGraphicEvent([self]() { self->OnProgressTick(); });
 }
 
+/** 开始进度会话 */
 void BPMainPresenter::StartProgressSession(BPProgressMode mode) {
   StopProgressSession();
   progressMode_ = mode;
@@ -122,6 +132,9 @@ void BPMainPresenter::StartProgressSession(BPProgressMode mode) {
   progressDataReceived_ = false;
   progressPaused_ = false;
   UpdateProgressUi(0);
+  StartPpgSession(mode);
+  uapi_set_screen_on_api();
+  SetScreenAlwaysOnForBp(true);
 
   const uint32_t tick = GetOSTick(static_cast<int32_t>(kProgressTickMs));
   progressTimer_ = new GraphicTimer(static_cast<int32_t>(tick), ProgressTimerThunk, this, true);
@@ -135,7 +148,10 @@ void BPMainPresenter::PauseProgressSession() { progressPaused_ = true; }
 
 void BPMainPresenter::ResumeProgressSession() { progressPaused_ = false; }
 
+/** 停止进度会话 */
 void BPMainPresenter::StopProgressSession() {
+  SetScreenAlwaysOnForBp(false);
+  StopPpgSession();
   if (progressTimer_ != nullptr) {
     progressTimer_->Stop();
     delete progressTimer_;
@@ -147,6 +163,92 @@ void BPMainPresenter::StopProgressSession() {
   progressPaused_ = false;
 }
 
+/** 判断血压读数是否有效 */
+bool BPMainPresenter::IsValidBpReading(int sbp, int dbp) {
+  return sbp >= 60 && sbp <= 250 && dbp >= 40 && dbp <= 150 && sbp > dbp;
+}
+
+/** 开始PPG会话 */
+void BPMainPresenter::StartPpgSession(BPProgressMode mode) {
+#ifdef SUPPORT_PPG_SERVICE
+  BPModel *model = BPModel::GetInstance();
+  if (mode == BPProgressMode::Calibrate) {
+    int sbp = static_cast<int>(model->GetInputSbp());
+    int dbp = static_cast<int>(model->GetInputDbp());
+    ppg_set_bp_cali_data(&sbp, &dbp);
+    ppg_bp_start(0);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BP] ppg cali start sbp=%d dbp=%d", sbp, dbp);
+  } else if (mode == BPProgressMode::Measure) {
+    ppg_bp_start(1);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BP] ppg measure start");
+  }
+#else
+  (void)mode;
+#endif
+}
+
+/** 停止PPG会话 */
+void BPMainPresenter::StopPpgSession() {
+#ifdef SUPPORT_PPG_SERVICE
+  if (progressMode_ != BPProgressMode::None) {
+    ppg_bp_stop();
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BP] ppg stop");
+  }
+#endif
+}
+
+void BPMainPresenter::SetScreenAlwaysOnForBp(bool enable) {
+  if (enable) {
+    if (!screenAlwaysOnForBp_) {
+      ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON);
+      screenAlwaysOnForBp_ = true;
+    }
+    return;
+  }
+  if (screenAlwaysOnForBp_) {
+    ScreenAlwaysOnCtr(CANCEL_SCREEN_ALWAYS_ON);
+    screenAlwaysOnForBp_ = false;
+  }
+}
+
+/** 轮询PPG结果 */
+bool BPMainPresenter::PollPpgResult() {
+#ifdef SUPPORT_PPG_SERVICE
+  int sbp = 0;
+  int dbp = 0;
+  ppg_get_bp(&sbp, &dbp);
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BP] PollPpgResult mode=%d sbp=%d dbp=%d",
+                static_cast<int>(progressMode_), sbp, dbp);
+
+  if (progressMode_ == BPProgressMode::Measure) {
+    if (!IsValidBpReading(sbp, dbp)) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BP] measure poll invalid sbp=%d dbp=%d", sbp, dbp);
+      return false;
+    }
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BP] measure result sbp=%d dbp=%d", sbp, dbp);
+    NotifyMeasureComplete(static_cast<uint8_t>(sbp), static_cast<uint8_t>(dbp));
+    return true;
+  }
+
+  if (progressMode_ == BPProgressMode::Calibrate) {
+    /* 校准模式:算法产出 NoCal 值即表示本轮回合采集完成 */
+    if (sbp <= 0 || dbp <= 0) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BP] cali poll no result sbp=%d dbp=%d", sbp, dbp);
+      return false;
+    }
+    BPModel *model = BPModel::GetInstance();
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "[BP] cali algorithm done, use input sbp=%d dbp=%d (algo nocall %d/%d)",
+                  model->GetInputSbp(), model->GetInputDbp(), sbp, dbp);
+    NotifyCalibrationComplete(model->GetInputSbp(), model->GetInputDbp());
+    return true;
+  }
+#else
+  (void)0;
+#endif
+  return false;
+}
+
 void BPMainPresenter::UpdateProgressUi(int percent) {
   if (progressMode_ == BPProgressMode::Measure) {
     BPMeasuringView *view = BPMeasuringView::GetInstance();
@@ -161,6 +263,7 @@ void BPMainPresenter::UpdateProgressUi(int percent) {
   }
 }
 
+/** 进度定时器回调 */
 void BPMainPresenter::OnProgressTick() {
   if (progressPaused_ || progressDataReceived_ || progressMode_ == BPProgressMode::None) {
     return;
@@ -173,11 +276,17 @@ void BPMainPresenter::OnProgressTick() {
   UpdateProgressUi(progressPercent_);
 
   if (progressPercent_ >= kProgressMaxPercent && !progressDataReceived_) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BP] progress 100%%, poll ppg result");
+    if (PollPpgResult()) {
+      return;
+    }
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BP] poll failed, goto timeout");
     lastTimeoutMode_ = progressMode_;
     OnProgressTimeout();
   }
 }
 
+/** 进度超时回调 */
 void BPMainPresenter::OnProgressTimeout() {
   StopProgressSession();
   BPMainView *mainView = BPMainView::GetInstance();
@@ -229,6 +338,7 @@ void BPMainPresenter::CompleteMeasureFlow(uint8_t sbp, uint8_t dbp) {
   }
 }
 
+/** 通知校准完成 */
 void BPMainPresenter::NotifyCalibrationComplete(uint8_t sbp, uint8_t dbp) {
   if (progressDataReceived_) {
     return;
@@ -239,6 +349,7 @@ void BPMainPresenter::NotifyCalibrationComplete(uint8_t sbp, uint8_t dbp) {
   CompleteCalibrationFlow(sbp, dbp);
 }
 
+/** 通知测量完成 */
 void BPMainPresenter::NotifyMeasureComplete(uint8_t sbp, uint8_t dbp) {
   if (progressDataReceived_) {
     return;
@@ -295,12 +406,14 @@ void BPMainPresenter::OnSwipe(UISwipeView &view) {
   }
 }
 
+/** 开始测量流程 */
 void BPMainPresenter::StartMeasureFlow(BPMainView *mainView) {
   int16_t hide = mainView->GetCurrentViewId();
   mainView->ChangeView(hide, BP_MEASURING_VIEW);
   StartProgressSession(BPProgressMode::Measure);
 }
 
+/** 开始校准流程 */
 void BPMainPresenter::StartCalibrationFlow(BPMainView *mainView, uint8_t round) {
   BPModel *model = BPModel::GetInstance();
   model->SetCalibrationRound(round);
@@ -309,6 +422,7 @@ void BPMainPresenter::StartCalibrationFlow(BPMainView *mainView, uint8_t round)
   mainView->ChangeView(hide, BP_VALUE_INPUT_VIEW);
 }
 
+/** 处理点击事件 */
 bool BPMainPresenter::OnClick(UIView &view, const ClickEvent &event) {
   UNUSED(event);
   std::string viewId = view.GetViewId();
@@ -340,6 +454,7 @@ bool BPMainPresenter::OnClick(UIView &view, const ClickEvent &event) {
     mainView->ChangeView(BP_ENTRY_VIEW, BP_INSTRUCTION_VIEW, BP_INSTRUCTION_TYPE_SEAT);
     return true;
   }
+  /** 处理值输入事件 */
   if (viewId == BP_CLICK_VALUE_NEXT) {
     BPValueInputView *inputView = BPValueInputView::GetInstance();
     if (inputView != nullptr && inputView->GetSbpPicker() != nullptr &&
@@ -352,6 +467,7 @@ bool BPMainPresenter::OnClick(UIView &view, const ClickEvent &event) {
     mainView->ChangeView(BP_VALUE_INPUT_VIEW, BP_VALUE_CONFIRM_VIEW);
     return true;
   }
+  /** 处理值确认事件 */
   if (viewId == BP_CLICK_VALUE_CONFIRM) {
     if (model->GetInputSbp() > model->GetInputDbp()) {
       mainView->ChangeView(BP_VALUE_CONFIRM_VIEW, BP_CALIBRATING_VIEW);
@@ -401,6 +517,7 @@ bool BPMainPresenter::OnClick(UIView &view, const ClickEvent &event) {
     mainView->ChangeView(current, BP_ENTRY_VIEW);
     return true;
   }
+  /** 处理重试事件 */
   if (viewId == BP_CLICK_RETRY) {
     if (current == BP_ABNORMAL_VIEW) {
       if (lastTimeoutMode_ == BPProgressMode::Calibrate) {
index e839dd8..bb4d152 100644 (file)
@@ -45,6 +45,9 @@ private:
   void ShowWaitContact(ECGMainView *mainView);
   void ShowContactGood(ECGMainView *mainView);
   bool IsWaitingContact(ECGMainView *mainView) const;
+  void SetScreenAlwaysOnForEcg(bool enable);
+
+  bool screenAlwaysOnForEcg_{false};
 };
 
 } // namespace OHOS
index adc2fea..591d934 100644 (file)
@@ -63,6 +63,7 @@ static void ECGContactGoodTimerCallback(void *arg) {
 ECGMainPresenter::ECGMainPresenter() { g_pECGMainPresenter = this; }
 
 ECGMainPresenter::~ECGMainPresenter() {
+  SetScreenAlwaysOnForEcg(false);
   StopMeasureTimer();
   StopContactGoodTimer();
   g_pECGMainPresenter = nullptr;
@@ -76,9 +77,14 @@ void ECGMainPresenter::OnPause(void) {}
 
 void ECGMainPresenter::OnResume(void) {
   RootView::GetInstance()->SetOnKeyActListener(this);
+  ECGMainView *mainView = ECGMainView::GetInstance();
+  if (mainView != nullptr && mainView->GetCurrentViewId() == ECG_MEASURING_VIEW) {
+    SetScreenAlwaysOnForEcg(true);
+  }
 }
 
 void ECGMainPresenter::OnStop(void) {
+  SetScreenAlwaysOnForEcg(false);
   StopMeasureTimer();
   StopContactGoodTimer();
 }
@@ -157,6 +163,8 @@ bool ECGMainPresenter::HandleSwipeBack() {
 
 void ECGMainPresenter::StartMeasureTimer() {
   StopMeasureTimer();
+  uapi_set_screen_on_api();
+  SetScreenAlwaysOnForEcg(true);
   g_ecgMeasureTimer =
       osTimerNew((osTimerFunc_t)ECGMeasureTimerCallback, osTimerPeriodic, nullptr, nullptr);
   if (g_ecgMeasureTimer != nullptr) {
@@ -165,6 +173,7 @@ void ECGMainPresenter::StartMeasureTimer() {
 }
 
 void ECGMainPresenter::StopMeasureTimer() {
+  SetScreenAlwaysOnForEcg(false);
   if (g_ecgMeasureTimer != nullptr) {
     osTimerStop(g_ecgMeasureTimer);
     osTimerDelete(g_ecgMeasureTimer);
@@ -172,6 +181,20 @@ void ECGMainPresenter::StopMeasureTimer() {
   }
 }
 
+void ECGMainPresenter::SetScreenAlwaysOnForEcg(bool enable) {
+  if (enable) {
+    if (!screenAlwaysOnForEcg_) {
+      ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON);
+      screenAlwaysOnForEcg_ = true;
+    }
+    return;
+  }
+  if (screenAlwaysOnForEcg_) {
+    ScreenAlwaysOnCtr(CANCEL_SCREEN_ALWAYS_ON);
+    screenAlwaysOnForEcg_ = false;
+  }
+}
+
 void ECGMainPresenter::StartMeasureFlow(ECGMainView *mainView) {
   ShowWaitContact(mainView);
 }