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};
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};
progressPercent_ = 0;
progressDataReceived_ = false;
progressPaused_ = false;
+ calibAlgorithmDone_ = false;
+ pollElapsedMs_ = 0;
UpdateProgressUi(0);
StartPpgSession(mode);
uapi_set_screen_on_api();
progressPercent_ = 0;
progressDataReceived_ = false;
progressPaused_ = false;
+ calibAlgorithmDone_ = false;
+ pollElapsedMs_ = 0;
}
/** 判断血压读数是否有效 */
}
}
-/** 轮询PPG结果 */
+/** 轮询 PPG 结果:测量模式成功则立即完成;校准模式仅标记算法完成,等待进度结束 */
bool BPMainPresenter::PollPpgResult() {
#ifdef SUPPORT_PPG_SERVICE
int sbp = 0;
}
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
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();
return;
}
+ pollElapsedMs_ += kProgressTickMs;
+ if (pollElapsedMs_ >= kPollIntervalMs) {
+ pollElapsedMs_ -= kPollIntervalMs;
+ PollPpgResult();
+ if (progressDataReceived_) {
+ return;
+ }
+ }
+
progressPercent_ += 1;
if (progressPercent_ > kProgressMaxPercent) {
progressPercent_ = kProgressMaxPercent;
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");
#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 {
UILabel *bpmValueLabel_{nullptr};
UILabel *bpmUnitLabel_{nullptr};
UILabel *resultLabel_{nullptr};
+ UILabel *noteLabel_{nullptr};
UILabelButton *confirmButton_{nullptr};
};
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);
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);
#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;
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;
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()));