/*---------------------------------------------------------------------------- * Copyright (c) TJD Technologies Co., Ltd. 2025. All rights reserved. * * Description: TjdUiAppCallPresenter.cpp * * Author: luziquan@ss-tjd.com * * Create: 2025-08-16 *--------------------------------------------------------------------------*/ #include "TjdUiAppCallPresenter.h" #include "NativeAbility.h" #include "TjdPhoneContacts.h" #include "TjdPhoneService.h" #include "TjdUiAppCallModel.h" #include "TjdUiAppCallView.h" #include "TjdUiAppIds.h" #include "TjdUiAppPhoneModel.h" #include "TjdUiRegisterManager.h" #include "dock/input_device.h" #include "graphic_service.h" #include "sys_config.h" #include #define ENABLE_PRINT_INFO 1 #if ENABLE_PRINT_INFO #define static_print_info(...) sys_ui_log_i(__VA_ARGS__) // 一般信息打印宏控制 #define static_print_warn(...) sys_ui_log_w(__VA_ARGS__) // 警告信息打印一般常开 #define static_print_error(...) sys_ui_log_e(__VA_ARGS__) // 错误信息打印一般常开 #define static_print_debug(...) sys_ui_log_d(__VA_ARGS__) // 调试信息打印一般常开 #else #define static_print_info(...) #define static_print_warn(...) #define static_print_error(...) #define static_print_debug(...) #endif namespace TJD { TJD_REGIST_SLICE(TJD_APP_VIEW_CALL, TjdUiAppCallView, TjdUiAppCallPresenter); static int g_callTimes{0}; class CallInListener : public OHOS::RootView::OnKeyActListener, public OHOS::UIView::OnClickListener { public: bool OnClick(OHOS::UIView &view, const OHOS::ClickEvent &event) override { std::string viewId = view.GetViewId(); if (viewId.empty()) { return false; } if (viewId == BTN_CALL_IN_STOP_VIEW_ID) { TjdUiAppPhoneModel::GetInstance().CallInReject(); } else if (viewId == BTN_CALL_IN_ANSWER_VIEW_ID) { TjdUiAppCallModel::GetInstance().SetShowViewType(ShowCallViewType::CALLING_VIEW); OHOS::NativeAbility::GetInstance().ChangeSlice(TJD_APP_VIEW_CALL); TjdUiAppPhoneModel::GetInstance().CallInAnswer(); } OHOS::NotificationManager::GetInstance()->StopNotify(); return true; } bool OnKeyAct(OHOS::UIView &view, const OHOS::KeyEvent &event) override { if (!TjdUiCommonOnKeyListener::CheckIsExitEvent(event)) { return true; } /* 第一次静音 */ if (keyCount_ == 0) { TjdUiAppPhoneModel::GetInstance().SetMuteCall(true); keyCount_++; } else { /* 第二次挂断 */ TjdUiAppPhoneModel::GetInstance().CallInReject(); keyCount_ = 0; } return true; } private: int keyCount_{0}; }; static CallInView *messageCallInView = nullptr; static CallInListener *callInListener = nullptr; /* 来电消息 */ void TjdUiPhoneMsgCenterMessageProc(const Topic topic, Request *req) { OHOS::NotificationManager::GetInstance()->SetNotifyPriority(TjdUiMsgCenterGetPriority(topic)); static_print_debug("TjdUiPhoneMsgCenterMessageProc topic = %d", topic); hfp_hf_calls_info_t *data = static_cast(req->data); if (data == nullptr) { static_print_error("TjdUiPhoneMsgCenterMessageProc data is nullptr"); return; } if (data->number_len > 0) { const ContactInfo *contact = FindContactOfNumber(reinterpret_cast(data->number), static_cast(data->number_len)); if (contact != nullptr) { TjdUiAppCallModel::GetInstance().SetCallingTest(contact->name); static_print_info("TjdUiPhoneMsgCenterMessageProc name = %s", contact->name.c_str()); } else { std::string number(data->number, data->number_len); TjdUiAppCallModel::GetInstance().SetCallingTest(number); static_print_info("TjdUiPhoneMsgCenterMessageProc number = %s", number.c_str()); } } OHOS::NotificationManager::GetInstance()->ShowNotify( []() -> CallInView * { if (messageCallInView == nullptr) { messageCallInView = new CallInView(); callInListener = new CallInListener(); messageCallInView->SetMsgClickEvent(callInListener); TjdUiCommonOnKeyListener::GetInstance()->SetOnKeyActListener(callInListener, KeyModelType::SYS_KEY_TYPE); } messageCallInView->SetCallName(TjdUiAppCallModel::GetInstance().GetCallingNumber()); OHOS::NotificationManager::GetInstance()->RegisterNotifyCleanupFunction([]() { OHOS::NotificationManager::GetInstance()->SetNotifyPriority(TJD_UI_PRIO_LOWEST); if (messageCallInView != nullptr) { TjdUiCommonOnKeyListener::GetInstance()->ClearOnKeyActListener(KeyModelType::SYS_KEY_TYPE); OHOS::RootView::GetInstance()->Remove(messageCallInView); messageCallInView->RemoveAll(); delete messageCallInView; delete callInListener; messageCallInView = nullptr; callInListener = nullptr; } static_print_debug("CallIn PageFree"); RunPopOutPageCallback(); }); return messageCallInView; }, static_cast(topic), true); } int16_t TjdUiAppCallPresenter::quickChangeSlice = -1; static TjdUiAppCallPresenter *g_callPresenter = nullptr; TjdUiAppCallPresenter::TjdUiAppCallPresenter() { g_callPresenter = this; } TjdUiAppCallPresenter::~TjdUiAppCallPresenter() { g_callPresenter = nullptr; } TjdUiAppCallPresenter *TjdUiAppCallPresenter::GetInstance(void) { return g_callPresenter; } void TjdUiAppCallPresenter::OnStart() { TjdUiCommonOnKeyListener::GetInstance()->SetOnKeyActListener(this, KeyModelType::APP_KEY_TYPE); TjdUiAppCallModel &callModel = TjdUiAppCallModel::GetInstance(); TjdUiAppCallView *callView = TjdUiAppCallView::GetInstance(); if (callView == nullptr) { return; } /* 设置初始音量 */ unsigned char curVolume = GetHFPCallCurrVolume(); // 0-15 -> 0-100 curVolume = curVolume * 100 / 15; callView->ChangeVolumeControlBarValue(curVolume); ShowCallViewType type = callModel.GetShowViewType(); if (type == ShowCallViewType::CALL_OUT_VIEW) { callView->ShowView(CallViewIndex::CALL_CALL_OUT); } else if (type == ShowCallViewType::CALLING_VIEW) { callView->ShowView(CallViewIndex::CALL_CALLING); StartCallingTimer(); } } void TjdUiAppCallPresenter::OnStop() { TjdUiCommonOnKeyListener::GetInstance()->ClearOnKeyActListener(KeyModelType::APP_KEY_TYPE); StopCallingTimer(); TjdUiAppPhoneModel::GetInstance().SetMuteCall(false); TjdUiAppCallModel::GetInstance().CallOutCallBackList(); } bool TjdUiAppCallPresenter::OnClick(OHOS::UIView &view, const OHOS::ClickEvent &event) { static_print_debug("TjdUiAppCallPresenter::OnClick"); std::string viewId = view.GetViewId(); if (viewId.empty()) { return false; } if (viewId == BTN_DIAL_CALL_END_VIEW_ID) { TjdUiAppPhoneModel::GetInstance().DialCallEnd(); } return false; } bool TjdUiAppCallPresenter::OnKeyAct(OHOS::UIView &view, const OHOS::KeyEvent &event) { return false; } bool TjdUiAppCallPresenter::OnRotateStart(OHOS::UIView &view, const OHOS::RotateEvent &event) { TjdUiAppCallView *callView = TjdUiAppCallView::GetInstance(); if (callView == nullptr) { return false; } callView->SetVolumeControlBarVisable(true); StartHideVolumeBarTimer(); return false; } bool TjdUiAppCallPresenter::OnRotate(OHOS::UIView &view, const OHOS::RotateEvent &event) { TjdUiAppCallView *callView = TjdUiAppCallView::GetInstance(); if (callView == nullptr) { return false; } constexpr uint8_t ROTATE_FACTOR = 5; const int value = event.GetRotate() > 0 ? -ROTATE_FACTOR : ROTATE_FACTOR; int curVolume = callView->ChangeVolumeControlBarValue(value); // 0-100 -> 0-15 curVolume = curVolume * 15 / 100; SetHFPSpeakerVolume(curVolume); static_print_debug("OnRotate %d", curVolume); ResetHideVolumeBarTimer(); return false; } void TjdUiAppCallPresenter::PhoneServiceCallChangedCb(std::string name, int state) { static_print_debug("TjdUiAppPhonePresenter::PhoneServiceCallChangedCb state: %d", state); TjdUiAppCallView *phoneView = TjdUiAppCallView::GetInstance(); if (phoneView == nullptr) { return; } if (state == HFP_HF_CALL_STATE_ACTIVE) { // 正在通话 phoneView->ShowView(CallViewIndex::CALL_CALLING); StartCallingTimer(); } else if (state == HFP_HF_CALL_STATE_HELD) { // 呼叫保持通话 } else if (state == HFP_HF_CALL_STATE_DIALING) { // 呼叫正在拨号 } else if (state == HFP_HF_CALL_STATE_ALERTING) { // 呼叫正在响铃 } else if (state == HFP_HF_CALL_STATE_INCOMING) { // 呼叫接入 } else if (state == HFP_HF_CALL_STATE_WAITING) { // 呼叫等待 } else if (state == HFP_HF_CALL_STATE_RESPONSE_HELD) { // 呼叫响应保持 } else if (state == HFP_HF_CALL_STATE_FINISHED) { // 呼叫结束 if (TjdUiAppCallView::currentViewIndex_ == CallViewIndex::CALL_CALL_OUT) { if (TjdUiAppCallPresenter::quickChangeSlice != -1) { OHOS::NativeAbility::GetInstance().ChangeSlice(quickChangeSlice); TjdUiAppCallPresenter::quickChangeSlice = -1; } else { OHOS::NativeAbility::GetInstance().ChangePreSlice(); } } else if (TjdUiAppCallView::currentViewIndex_ == CallViewIndex::CALL_CALLING) { phoneView->ShowView(CALL_END); StopCallingTimer(); StartJumpTimer(); } } } std::string &TjdUiAppCallPresenter::GetCallingNumber(void) { TjdUiAppCallModel &callModel = TjdUiAppCallModel::GetInstance(); return callModel.GetCallingNumber(); } void TjdUiAppCallPresenter::StartJumpTimer() { if (jumpTimerId_ == nullptr) { jumpTimerId_ = osTimerNew( [](void *arg) { GraphicService::GetInstance()->PostGraphicEvent([]() { if (TjdUiAppCallPresenter::quickChangeSlice != -1) { OHOS::NativeAbility::GetInstance().ChangeSlice(quickChangeSlice); TjdUiAppCallPresenter::quickChangeSlice = -1; } else { OHOS::NativeAbility::GetInstance().ChangePreSlice(); } }); }, osTimerOnce, nullptr, nullptr); if (jumpTimerId_ == nullptr) { static_print_error("TjdUiAppPhonePresenter::StartJumpTimer Create timer fail."); return; } } int32_t ret = osTimerStart(jumpTimerId_, 2000); if (ret != 0) { static_print_error("TjdUiAppPhonePresenter::StartJumpTimer Start timer fail"); return; } } void TjdUiAppCallPresenter::StartHideVolumeBarTimer() { if (volumeBarHideTimerId_ == nullptr) { volumeBarHideTimerId_ = osTimerNew( [](void *arg) { GraphicService::GetInstance()->PostGraphicEvent([]() { TjdUiAppCallView *callView = TjdUiAppCallView::GetInstance(); if (callView == nullptr) { return; } callView->SetVolumeControlBarVisable(false); }); }, osTimerOnce, 0, nullptr); if (volumeBarHideTimerId_ == nullptr) { static_print_error("TjdUiAppCallPresenter::StartHideVolumeBarTimer Create timer fail."); return; } } int32_t ret = osTimerStart(volumeBarHideTimerId_, 2000); if (ret != 0) { static_print_error("TjdUiAppCallPresenter::StartHideVolumeBarTimer Start timer fail"); return; } } void TjdUiAppCallPresenter::ResetHideVolumeBarTimer() { if (volumeBarHideTimerId_ == nullptr) { return; } int32_t ret = osTimerStop(volumeBarHideTimerId_); if (ret != 0) { static_print_error("TjdUiAppCallPresenter::ResetHideVolumeBarTimer timer fail"); return; } StartHideVolumeBarTimer(); } void TjdUiAppCallPresenter::StopCallingTimer() { if (CountingTimerId_ != nullptr) { osStatus_t ret = osTimerDelete(CountingTimerId_); if (ret != osOK) { static_print_error("ScanTimerCallback osTimerDelete failed, ret = %lx!!", ret); return; } CountingTimerId_ = nullptr; g_callTimes = 0; } } void TjdUiAppCallPresenter::CallTimerCallbackProc(int data) { g_callTimes++; TjdUiAppCallView *callView = TjdUiAppCallView::GetInstance(); if (callView == nullptr) { static_print_debug("[phonView] GetInstance is nullptr"); return; } callView->SetCallingTime(DisplayCallDuration()); } void TjdUiAppCallPresenter::StartCallingTimer() { g_callTimes = TjdUiAppCallModel::GetInstance().GetCallTime(); static_print_debug("TjdUiAppPhonePresenter::StartJumpTimer g_callTimes: %d", g_callTimes); if (CountingTimerId_ != nullptr) { static_print_debug("TjdUiAppCallPresenter::CountingTimerId_ already exists!!"); return; } CountingTimerId_ = osTimerNew( [](void *argument) { GraphicService::GetInstance()->PostGraphicEvent([]() { TjdUiAppCallPresenter *presenter = TjdUiAppCallPresenter::GetInstance(); if (presenter == nullptr) { return; } presenter->CallTimerCallbackProc(0); }); }, osTimerPeriodic, nullptr, nullptr); if (CountingTimerId_ == nullptr) { static_print_error("CallerLogModel::CallerTimer osTimerNew failed!!"); return; } int tick = osMs2Tick(1000); osStatus_t retTimer = osTimerStart(CountingTimerId_, tick); if (retTimer != osOK) { static_print_error("CallerLogModel::CallerTimer osTimerStart failed, ret = %lx!!", retTimer); if (CountingTimerId_ != nullptr) { retTimer = osTimerDelete(CountingTimerId_); if (retTimer != osOK) { static_print_error("CallerLogModel::osTimerDelete failed, ret = %lx!!", retTimer); return; } CountingTimerId_ = nullptr; } return; } } std::string &TjdUiAppCallPresenter::DisplayCallDuration() { callDuration.erase(); std::string hours; std::string minute; std::string seconds; if (g_callTimes >= 86400) { g_callTimes = 0; } int hour = g_callTimes / 3600; int min = (g_callTimes % 3600) / 60; int sec = (g_callTimes % 3600) % 60; if (hour >= 0 && hour < 10) { hours = "0" + std::to_string(hour); } else { hours = std::to_string(hour); } if (min >= 0 && min < 10) { minute = "0" + std::to_string(min); } else { minute = std::to_string(min); } if (sec >= 0 && sec < 10) { seconds = "0" + std::to_string(sec); } else { seconds = std::to_string(sec); } if (hour == 0) { callDuration = minute + ":" + seconds; } else { callDuration = hours + ":" + minute + ":" + seconds; } return callDuration; } } // namespace TJD