From b16c42afff9d143c3374594394eab3acefbf61fe Mon Sep 17 00:00:00 2001 From: xue <2144439972@qq.com> Date: Tue, 9 Jun 2026 12:00:19 +0800 Subject: [PATCH] =?utf8?q?=E4=BC=98=E5=8C=96=E6=B5=8B=E9=87=8F=E6=B5=81?= =?utf8?q?=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../bloodpressure/include/BPMainPresenter.h | 9 +- .../bloodpressure/src/BPCalibratingView.cpp | 7 +- .../bloodpressure/src/BPMainPresenter.cpp | 117 ++++++++++++++++++ .../nativeui/ecg/include/ECGMainPresenter.h | 3 + .../nativeui/ecg/src/ECGMainPresenter.cpp | 23 ++++ 5 files changed, 156 insertions(+), 3 deletions(-) diff --git a/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/include/BPMainPresenter.h b/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/include/BPMainPresenter.h index 04ae824eb..9ca6101fe 100644 --- a/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/include/BPMainPresenter.h +++ b/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/include/BPMainPresenter.h @@ -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 diff --git a/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/src/BPCalibratingView.cpp b/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/src/BPCalibratingView.cpp index fd9f8b8c0..bd606d129 100644 --- a/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/src/BPCalibratingView.cpp +++ b/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/src/BPCalibratingView.cpp @@ -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"); diff --git a/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/src/BPMainPresenter.cpp b/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/src/BPMainPresenter.cpp index 1f8a45a99..6904bbdae 100644 --- a/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/src/BPMainPresenter.cpp +++ b/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/src/BPMainPresenter.cpp @@ -21,6 +21,11 @@ #include #include +#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(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(kProgressTickMs)); progressTimer_ = new GraphicTimer(static_cast(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(model->GetInputSbp()); + int dbp = static_cast(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(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(sbp), static_cast(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) { diff --git a/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/include/ECGMainPresenter.h b/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/include/ECGMainPresenter.h index e839dd830..bb4d1521c 100644 --- a/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/include/ECGMainPresenter.h +++ b/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/include/ECGMainPresenter.h @@ -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 diff --git a/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/src/ECGMainPresenter.cpp b/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/src/ECGMainPresenter.cpp index adc2fea6b..591d93406 100644 --- a/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/src/ECGMainPresenter.cpp +++ b/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/src/ECGMainPresenter.cpp @@ -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); } -- 2.17.1