优化定时器处理
authorxue <2144439972@qq.com>
Wed, 10 Jun 2026 09:11:05 +0000 (17:11 +0800)
committerxue <2144439972@qq.com>
Wed, 10 Jun 2026 09:11:05 +0000 (17:11 +0800)
code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/include/BPMainPresenter.h
code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/src/BPMainPresenter.cpp
code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/include/ECGMeasureResultView.h
code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/src/ECGInstructionView.cpp
code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/src/ECGMeasureResultView.cpp

index 9ca6101..0fdcb98 100644 (file)
@@ -60,11 +60,13 @@ private:
   void StopPpgSession();
   void SetScreenAlwaysOnForBp(bool enable);
   bool PollPpgResult();
+  void TryCompleteCalibrationAtEnd();
   static bool IsValidBpReading(int sbp, int dbp);
   static void ProgressTimerThunk(void *arg);
 
-  /** 约 30s 完成(算法需 ~30s ECG 采集) */
+  /** 约 30s 完成(300ms × 100 步) */
   static constexpr uint32_t kProgressTickMs = 300U;
+  static constexpr uint32_t kPollIntervalMs = 1000U;
   static constexpr int kProgressMaxPercent = 100;
 
   GraphicTimer *progressTimer_{nullptr};
@@ -72,6 +74,8 @@ private:
   int progressPercent_{0};
   bool progressDataReceived_{false};
   bool progressPaused_{false};
+  bool calibAlgorithmDone_{false};
+  uint32_t pollElapsedMs_{0};
   int16_t stopReturnView_{MAX_BPVIEW};
   bool stopIsMeasure_{false};
   BPProgressMode lastTimeoutMode_{BPProgressMode::None};
index a6e81c1..1cbe4c2 100644 (file)
@@ -131,6 +131,8 @@ void BPMainPresenter::StartProgressSession(BPProgressMode mode) {
   progressPercent_ = 0;
   progressDataReceived_ = false;
   progressPaused_ = false;
+  calibAlgorithmDone_ = false;
+  pollElapsedMs_ = 0;
   UpdateProgressUi(0);
   StartPpgSession(mode);
   uapi_set_screen_on_api();
@@ -161,6 +163,8 @@ void BPMainPresenter::StopProgressSession() {
   progressPercent_ = 0;
   progressDataReceived_ = false;
   progressPaused_ = false;
+  calibAlgorithmDone_ = false;
+  pollElapsedMs_ = 0;
 }
 
 /** 判断血压读数是否有效 */
@@ -211,7 +215,7 @@ void BPMainPresenter::SetScreenAlwaysOnForBp(bool enable) {
   }
 }
 
-/** 轮询PPG结果 */
+/** 轮询 PPG 结果:测量模式成功则立即完成;校准模式仅标记算法完成,等待进度结束 */
 bool BPMainPresenter::PollPpgResult() {
 #ifdef SUPPORT_PPG_SERVICE
   int sbp = 0;
@@ -231,16 +235,15 @@ bool BPMainPresenter::PollPpgResult() {
   }
 
   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();
+    calibAlgorithmDone_ = true;
     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());
+                  "[BP] cali algorithm done (nocall %d/%d), wait progress end input sbp=%u dbp=%u",
+                  sbp, dbp, BPModel::GetInstance()->GetInputSbp(),
+                  BPModel::GetInstance()->GetInputDbp());
     return true;
   }
 #else
@@ -249,6 +252,14 @@ bool BPMainPresenter::PollPpgResult() {
   return false;
 }
 
+void BPMainPresenter::TryCompleteCalibrationAtEnd() {
+  if (progressMode_ != BPProgressMode::Calibrate || !calibAlgorithmDone_ || progressDataReceived_) {
+    return;
+  }
+  BPModel *model = BPModel::GetInstance();
+  NotifyCalibrationComplete(model->GetInputSbp(), model->GetInputDbp());
+}
+
 void BPMainPresenter::UpdateProgressUi(int percent) {
  if (progressMode_ == BPProgressMode::Calibrate) {
     BPCalibratingView *view = BPCalibratingView::GetInstance();
@@ -264,6 +275,15 @@ void BPMainPresenter::OnProgressTick() {
     return;
   }
 
+  pollElapsedMs_ += kProgressTickMs;
+  if (pollElapsedMs_ >= kPollIntervalMs) {
+    pollElapsedMs_ -= kPollIntervalMs;
+    PollPpgResult();
+    if (progressDataReceived_) {
+      return;
+    }
+  }
+
   progressPercent_ += 1;
   if (progressPercent_ > kProgressMaxPercent) {
     progressPercent_ = kProgressMaxPercent;
@@ -271,8 +291,13 @@ void BPMainPresenter::OnProgressTick() {
   UpdateProgressUi(progressPercent_);
 
   if (progressPercent_ >= kProgressMaxPercent && !progressDataReceived_) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BP] progress 100%%, poll ppg result");
-    if (PollPpgResult()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BP] progress 100%%, final poll");
+    PollPpgResult();
+    if (progressDataReceived_) {
+      return;
+    }
+    TryCompleteCalibrationAtEnd();
+    if (progressDataReceived_) {
       return;
     }
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BP] poll failed, goto timeout");
index 47639ba..b87cc5e 100644 (file)
@@ -6,8 +6,8 @@
 #include "components/ui_label_button.h"
 #include "components/ui_view_group.h"
 
-#define ECG_PATH_HEART_ICON "/user/res/heart_chart/hearticon.bin"
-#define ECG_PATH_RESULT_BACKGROUND "/user/res/ecg/result_background.bin"
+#define ECG_PATH_HEART_RED_ICON "/user/res/ecg/heart_red.bin"
+#define ECG_PATH_RESULT_BACKGROUND "/user/res/ecg/background.bin"
 namespace OHOS {
 
 class ECGMeasureResultView {
@@ -25,6 +25,7 @@ private:
   UILabel *bpmValueLabel_{nullptr};
   UILabel *bpmUnitLabel_{nullptr};
   UILabel *resultLabel_{nullptr};
+  UILabel *noteLabel_{nullptr};
   UILabelButton *confirmButton_{nullptr};
 };
 
index 25414d3..35f1354 100644 (file)
@@ -65,7 +65,7 @@ void ECGInstructionView::InitWaitContact() {
   InitUILabel(titleLabel_, 0, 50, 466, 35, "ecg_wait_contact_title", "ECG测量",
               DEFAULT_VECTOR_FONT_FILENAME, 30);
   titleLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
-  InitImageView(imageView_, 141, 36, 184, 184, "ecg_wait_contact", ECG_PATH_WAIT_CONTACT);
+  InitImageView(imageView_, 55, 95, 360, 300, "ecg_wait_contact", ECG_PATH_WAIT_CONTACT);
   InitUILabel(contentLabel_, 0, 401, 466, 30, "ecg_wait_contact_content", "将手指放在电极上",
               DEFAULT_VECTOR_FONT_FILENAME, 30);
   contentLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
@@ -82,7 +82,7 @@ void ECGInstructionView::InitContactGood() {
   InitUILabel(titleLabel_, 0, 50, 466, 35, "ecg_contact_good_title", "ECG测量",
               DEFAULT_VECTOR_FONT_FILENAME, 30);
   titleLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
-  InitImageView(imageView_, 141, 36, 184, 184, "ecg_contact_good", ECG_PATH_CONTACT_GOOD);
+  InitImageView(imageView_, 55, 95, 360, 300, "ecg_contact_good", ECG_PATH_CONTACT_GOOD);
   InitUILabel(contentLabel_, 0, 401, 466, 30, "ecg_contact_good_content", "保持手指不动",
               DEFAULT_VECTOR_FONT_FILENAME, 30);
   contentLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
index 259a1b1..db6c9fd 100644 (file)
@@ -6,6 +6,19 @@
 #include "uicomponents/UIComponents.h"
 
 namespace OHOS {
+namespace {
+static constexpr int16_t ECG_RESULT_ROW_Y = 168;
+static constexpr int16_t ECG_HEART_X = 129;
+static constexpr int16_t ECG_HEART_Y = ECG_RESULT_ROW_Y + 8;
+static constexpr int16_t ECG_HEART_W = 54;
+static constexpr int16_t ECG_HEART_H = 54;
+static constexpr int16_t ECG_BPM_X = ECG_HEART_X + ECG_HEART_W + 12;
+static constexpr int16_t ECG_BPM_Y = ECG_RESULT_ROW_Y;
+static constexpr int16_t ECG_BPM_W = 66;
+static constexpr int16_t ECG_BPM_H = 66;
+static constexpr int16_t ECG_BPM_UNIT_X = ECG_BPM_X + ECG_BPM_W + 8;
+static constexpr int16_t ECG_BPM_UNIT_Y = ECG_RESULT_ROW_Y + 35;
+} // namespace
 
 static ECGMeasureResultView *g_instance = nullptr;
 
@@ -18,12 +31,14 @@ ECGMeasureResultView::~ECGMeasureResultView() {
     delete bpmValueLabel_;
     delete bpmUnitLabel_;
     delete resultLabel_;
+    delete noteLabel_;
     delete confirmButton_;
     delete backgroundIcon_;
     delete group_;
     heartIcon_ = nullptr;
     backgroundIcon_ = nullptr;
     bpmValueLabel_ = nullptr;
+    noteLabel_ = nullptr;
     bpmUnitLabel_ = nullptr;
     resultLabel_ = nullptr;
     backgroundIcon_ = nullptr;
@@ -60,23 +75,29 @@ UIViewGroup *ECGMeasureResultView::InitView() {
 
   InitImageView(backgroundIcon_, 0, 43, 466, 380, "ecg_result_background", ECG_PATH_RESULT_BACKGROUND);
 
-  InitImageView(heartIcon_, 206, 100, 54, 50, "ecg_result_heart", ECG_PATH_HEART_ICON);
+  InitImageView(heartIcon_, ECG_HEART_X, ECG_HEART_Y, ECG_HEART_W, ECG_HEART_H, "ecg_result_heart",
+                ECG_PATH_HEART_RED_ICON);
 
-
-  InitUILabel(bpmValueLabel_, 0, 170, 466, 90, "ecg_result_bpm", "--",
-              DEFAULT_VECTOR_FONT_FILENAME, 72);
+  InitUILabel(bpmValueLabel_, ECG_BPM_X, ECG_BPM_Y, ECG_BPM_W, ECG_BPM_H, "ecg_result_bpm", "--",
+              DEFAULT_VECTOR_FONT_FILENAME, 65);
   bpmValueLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
 
-  InitUILabel(bpmUnitLabel_, 0, 250, 466, 30, "ecg_result_bpm_unit", "bpm",
-              DEFAULT_VECTOR_FONT_FILENAME, 26);
+  InitUILabel(bpmUnitLabel_, ECG_BPM_UNIT_X, ECG_BPM_UNIT_Y, 72, 30, "ecg_result_bpm_unit", "次/分",
+              DEFAULT_VECTOR_FONT_FILENAME, 30);
+
   bpmUnitLabel_->SetTextColor(Color::GetColorFromRGBA(0x99, 0x99, 0x99, 0xff));
   bpmUnitLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
 
-  InitUILabel(resultLabel_, 0, 290, 466, 40, "ecg_result_type", "窦性心律",
-              DEFAULT_VECTOR_FONT_FILENAME, 32);
+  InitUILabel(resultLabel_, 0, 50, 466, 35, "ecg_result_type", "窦性心律",
+              DEFAULT_VECTOR_FONT_FILENAME, 30);
   resultLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
 
-  InitLabelButton(confirmButton_, 93, 330, 280, 90, ECG_CLICK_CONFIRM, "完成", 30);
+  InitUILabel(noteLabel_, 0, 412, 466, 35, "ecg_result_note", "测量结果仅供参考",
+              DEFAULT_VECTOR_FONT_FILENAME, 30);
+  noteLabel_->SetTextColor(Color::GetColorFromRGBA(0x99, 0x99, 0x99, 0xff));
+  noteLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+
+  InitLabelButton(confirmButton_, 93, 304, 280, 90, ECG_CLICK_CONFIRM, "重新测量", 30);
   confirmButton_->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919);
   confirmButton_->SetStyle(STYLE_BORDER_RADIUS, 45);
   confirmButton_->SetOnClickListener(static_cast<UIView::OnClickListener *>(ECGMainPresenter::GetInstance()));