1603 lines
53 KiB
C++
1603 lines
53 KiB
C++
/*----------------------------------------------------------------------------
|
||
* Copyright (c) TJD Technologies Co., Ltd. 2025. All rights reserved.
|
||
*
|
||
* Description: TjdPhoneService.cpp
|
||
*
|
||
* Author: luziquan@ss-tjd.com
|
||
*
|
||
* Create: 2025-08-16
|
||
*--------------------------------------------------------------------------*/
|
||
|
||
#include "TjdPhoneService.h"
|
||
#include "TjdPhoneAudio.h"
|
||
#include "TjdPhoneContacts.h"
|
||
#include "TjdUiMsgCenter.h"
|
||
#include "TjdUiSettingCenter.h"
|
||
#include "audio_base_type.h"
|
||
#include "bts_pbap.h"
|
||
#include "graphic_service.h"
|
||
#include "service_bt.h"
|
||
#include "sys_config.h"
|
||
#include "thread_adapter.h"
|
||
#include "ui_screennotify.h"
|
||
#include <dirent.h>
|
||
#include <securec.h>
|
||
#include <stdio.h>
|
||
#include <sys/stat.h>
|
||
#include <time.h>
|
||
#include <unistd.h>
|
||
|
||
extern "C"
|
||
{
|
||
#include "power_display_service.h"
|
||
}
|
||
|
||
#define ENABLE_PRINT_INFO 1
|
||
#if ENABLE_PRINT_INFO
|
||
#define static_print_warn(...) sys_phone_log_w(__VA_ARGS__) // 警告信息打印一般常开
|
||
#define static_print_error(...) sys_phone_log_e(__VA_ARGS__) // 错误信息打印一般常开
|
||
#define static_print_debug(...) sys_phone_log_d(__VA_ARGS__) // 调试信息打印一般常开
|
||
#else
|
||
#define static_print_warn(...)
|
||
#define static_print_error(...)
|
||
#define static_print_debug(...)
|
||
#endif
|
||
|
||
typedef enum
|
||
{
|
||
AUDIO_UNKNOW = 0,
|
||
AUDIO_ACT_INTERRUPT_WATCH_RING, // 手表铃声焦点
|
||
AUDIO_ACT_INTERRUPT_BT_SCO, // 蓝牙通话焦点
|
||
AUDIO_CONN_IN_BT_SCO,
|
||
AUDIO_CONN_OUT_BT_SCO,
|
||
AUDIO_STREAM_INIT,
|
||
AUDIO_STREAM_START_SCO,
|
||
AUDIO_STREAM_START_DN,
|
||
AUDIO_STREAM_START_UP,
|
||
} AudioState;
|
||
|
||
#define TJD_CALL_LOG_DIR "/user/tjd_phone"
|
||
#define TJD_CALL_LOG_PATH (TJD_CALL_LOG_DIR "/calllog.bin")
|
||
#define TJD_CALL_TMP_LOG_PATH (TJD_CALL_LOG_DIR "/calltmplog.bin")
|
||
#define INVALID_PHONE_SERVICE_VALUE (-1)
|
||
|
||
static uint32_t g_scoFlag = HFP_SCO_STATE_DISCONNECTED; // sco连接状态,同时也表示通话在手表还是在手机
|
||
static uint32_t g_btConnState = PROFILE_STATE_DISCONNECTED; // 蓝牙连接状态
|
||
static uint32_t g_currCallState = HFP_HF_CALL_STATE_FINISHED; // 电话呼叫状态类型。
|
||
static bool g_completeCallFlag = false; // 完整通话流程:从incoming、dialing或alerting开始才算完整
|
||
static uint32_t g_call_codec = mSBC; // 通话编解码类型
|
||
static bd_addr_t g_bdAddr; // 设备的蓝牙地址
|
||
static uint32 g_currCallNum = 0; // 当前通话路数
|
||
static MutexId g_audioMutex;
|
||
static ContactsInfo g_callList[MULTI_CALL_MAX_NUME];
|
||
static uint32_t g_finishOperate = OPERATE_NON_WATCH_FINISH;
|
||
static uint32_t g_audioState = AUDIO_UNKNOW;
|
||
static uint32_t g_interval = 5;
|
||
|
||
static int g_hdlUpMic = INVALID_PHONE_SERVICE_VALUE;
|
||
static int g_hdlUpSco = INVALID_PHONE_SERVICE_VALUE;
|
||
static int g_hdlDnSpk = INVALID_PHONE_SERVICE_VALUE;
|
||
static int g_hdlDnSco = INVALID_PHONE_SERVICE_VALUE;
|
||
|
||
bd_addr_t *GetHfpBdAddr(void) { return &g_bdAddr; }
|
||
|
||
static void PostGraphicEvent(void (*fun)(void))
|
||
{
|
||
static_print_debug("[PostGraphicEvent] start");
|
||
GraphicService::GetInstance()->PostGraphicEvent(*fun);
|
||
}
|
||
|
||
static PhoneServiceCb g_callChanged;
|
||
int RegisterPhoneCallChangedCb(PhoneServiceCb *phoneServiceFun)
|
||
{
|
||
if (phoneServiceFun == nullptr) {
|
||
return OHOS_FAILURE;
|
||
}
|
||
(void)memcpy_s(&g_callChanged, sizeof(g_callChanged), phoneServiceFun, sizeof(g_callChanged));
|
||
return OHOS_SUCCESS;
|
||
}
|
||
|
||
static void ScreenTurnOn(int32_t timeout)
|
||
{
|
||
#if defined(SUPPORT_POWER_MANAGER)
|
||
g_interval = get_back_to_home_interval();
|
||
set_back_to_home_interval(0xFFFFFFFF);
|
||
const power_display_svr_api_t *display_api = power_display_svr_get_api();
|
||
if (display_api->get_screen_state() != SCREEN_ON) {
|
||
display_api->turn_on_screen();
|
||
}
|
||
display_api->set_screen_set_keepon_timeout(timeout);
|
||
#endif
|
||
return;
|
||
}
|
||
|
||
static void ScreenTurnOff(void)
|
||
{
|
||
#if defined(SUPPORT_POWER_MANAGER)
|
||
set_back_to_home_interval(g_interval);
|
||
const power_display_svr_api_t *display_api = power_display_svr_get_api();
|
||
display_api->set_screen_set_keepon_timeout(0);
|
||
#endif
|
||
return;
|
||
}
|
||
|
||
static void PhoneServiceScreenCtr(bool turnOnFlag)
|
||
{
|
||
if (turnOnFlag) {
|
||
ScreenTurnOn(-1);
|
||
} else {
|
||
ScreenTurnOff();
|
||
}
|
||
}
|
||
|
||
// 手表主动拨打电话
|
||
int DialCallOut(const unsigned char *number, unsigned char len)
|
||
{
|
||
int ret;
|
||
unsigned char *tel = nullptr;
|
||
static_print_debug("[DialCall] start");
|
||
if (g_btConnState != PROFILE_STATE_CONNECTED) {
|
||
static_print_error("[DialCall] BT connStatus: 0x%X", g_btConnState);
|
||
return OHOS_FAILURE;
|
||
}
|
||
|
||
// 有通话时,不允许拨出电话
|
||
if (g_currCallNum > 0 || len > MAX_PHONE_NUM || number == nullptr) {
|
||
static_print_error("[DialCall] g_currCallNum:%d", g_currCallNum);
|
||
return OHOS_FAILURE;
|
||
}
|
||
|
||
tel = (unsigned char *)malloc(len + 1);
|
||
if (tel == nullptr) {
|
||
static_print_error("[DialCall] malloc tel error");
|
||
return OHOS_FAILURE;
|
||
}
|
||
(void)memcpy_s(tel, len, number, len);
|
||
*(tel + len) = '\0';
|
||
ret = hfp_hf_start_dial(&g_bdAddr, tel, len);
|
||
if (ret != ERRCODE_BT_SUCCESS) {
|
||
static_print_error("[DialCall] hfp_hf_start_dial ret %d", ret);
|
||
free(tel);
|
||
return OHOS_FAILURE;
|
||
}
|
||
static_print_debug("[DialCall] success!");
|
||
free(tel);
|
||
return OHOS_SUCCESS;
|
||
}
|
||
|
||
// 手表主动接听
|
||
int AnswerCallIn(void)
|
||
{
|
||
static_print_debug("[AcceptIncomingCall] start");
|
||
int32_t ret;
|
||
ContactsInfo *phoneCall = nullptr;
|
||
ContactsInfo *tmp = g_callList;
|
||
|
||
if (g_btConnState != PROFILE_STATE_CONNECTED) {
|
||
static_print_error("[AcceptIncomingCall] BT connStatus: 0x%X", g_btConnState);
|
||
return OHOS_FAILURE;
|
||
}
|
||
|
||
for (int32_t i = 0; i < MULTI_CALL_MAX_NUME; i++) {
|
||
if (tmp->lastStatus == HFP_HF_CALL_STATE_INCOMING || tmp->lastStatus == HFP_HF_CALL_STATE_WAITING) {
|
||
phoneCall = tmp;
|
||
break;
|
||
}
|
||
tmp++;
|
||
}
|
||
|
||
if (phoneCall == nullptr) {
|
||
static_print_error("[AcceptIncomingCall] no incoming");
|
||
return OHOS_FAILURE;
|
||
}
|
||
|
||
phoneCall->operate = OPERATE_WATCH_ACTIVE;
|
||
|
||
if (g_currCallNum > 1) {
|
||
// 正在通话,有人呼入,接听呼入电话,挂起当前通话
|
||
ret = hfp_hf_accept_incoming_call(&g_bdAddr, HFP_HF_ACCEPT_CALL_ACTION_HOLD);
|
||
} else {
|
||
// 无人通话,有人呼入,接听呼入电话
|
||
ret = hfp_hf_accept_incoming_call(&g_bdAddr, HFP_HF_ACCEPT_CALL_ACTION_NONE);
|
||
}
|
||
if (ret != ERRCODE_BT_SUCCESS) {
|
||
static_print_error("[AcceptIncomingCall] ret:%d", ret);
|
||
phoneCall->operate = OPERATE_NO_OPE;
|
||
return OHOS_FAILURE;
|
||
}
|
||
static_print_debug("[AcceptIncomingCall] success!");
|
||
return OHOS_SUCCESS;
|
||
}
|
||
|
||
// 手表拒接呼入来电,成功:0,失败:错误码
|
||
int RejectCallIn(void)
|
||
{
|
||
static_print_debug("[RejectIncomingCall] start");
|
||
ContactsInfo *phoneCall = nullptr;
|
||
ContactsInfo *tmp = g_callList;
|
||
|
||
if (g_btConnState != PROFILE_STATE_CONNECTED) {
|
||
static_print_error("[RejectIncomingCall] BT connStatus: 0x%X", g_btConnState);
|
||
return OHOS_FAILURE;
|
||
}
|
||
|
||
for (int32_t i = 0; i < MULTI_CALL_MAX_NUME; i++) {
|
||
if (tmp->lastStatus == HFP_HF_CALL_STATE_INCOMING || tmp->lastStatus == HFP_HF_CALL_STATE_WAITING) {
|
||
phoneCall = tmp;
|
||
}
|
||
tmp++;
|
||
}
|
||
|
||
if (phoneCall == nullptr) {
|
||
static_print_error("[AcceptIncomingCall] no incoming");
|
||
return OHOS_SUCCESS;
|
||
}
|
||
|
||
int32_t ret = hfp_hf_reject_incoming_call(&g_bdAddr);
|
||
if (ret != ERRCODE_BT_SUCCESS) {
|
||
static_print_error("[RejectIncomingCall] ret:%d", ret);
|
||
return OHOS_FAILURE;
|
||
}
|
||
g_finishOperate = OPERATE_WATCH_REJECT;
|
||
static_print_debug("[RejectIncomingCall] success!");
|
||
return OHOS_SUCCESS;
|
||
}
|
||
|
||
// 手表结束通话
|
||
int DialCallFinish(void)
|
||
{
|
||
if (g_btConnState != PROFILE_STATE_CONNECTED) {
|
||
static_print_error("[FinishCall] BT connStatus: 0x%X", g_btConnState);
|
||
return OHOS_FAILURE;
|
||
}
|
||
if (g_currCallState != HFP_HF_CALL_STATE_ACTIVE && g_currCallState != HFP_HF_CALL_STATE_HELD &&
|
||
g_currCallState != HFP_HF_CALL_STATE_DIALING && g_currCallState != HFP_HF_CALL_STATE_ALERTING) {
|
||
static_print_error("[FinishCall] g_currCallState:%d", g_currCallState);
|
||
return OHOS_FAILURE;
|
||
}
|
||
int ret = hfp_hf_finish_call(&g_bdAddr);
|
||
if (ret != ERRCODE_BT_SUCCESS) {
|
||
static_print_error("[FinishCall] ret:%d", ret);
|
||
return OHOS_FAILURE;
|
||
}
|
||
g_finishOperate = OPERATE_WATCH_FINISH;
|
||
static_print_debug("FinishCall");
|
||
return OHOS_SUCCESS;
|
||
}
|
||
|
||
// 获取当前正在通话路数
|
||
int GetCurCallNumber(void) { return g_currCallNum; }
|
||
|
||
static void CallChangedCb(const ContactsInfo *phoneCall)
|
||
{
|
||
if (g_callChanged.callChanged != nullptr) {
|
||
g_callChanged.callChanged(phoneCall);
|
||
}
|
||
}
|
||
|
||
static void ScoStatusCb(hfp_sco_connect_state_t state)
|
||
{
|
||
if (g_callChanged.scoStatusCb != nullptr) {
|
||
g_callChanged.scoStatusCb(state);
|
||
}
|
||
}
|
||
|
||
static void PhoneServiceErrorCallback(PhoneServiceErrorType type, int volume)
|
||
{
|
||
if (g_callChanged.phoneServiceErrorCb != nullptr) {
|
||
g_callChanged.phoneServiceErrorCb(type, volume);
|
||
}
|
||
}
|
||
|
||
static void CopyBdAddr(const bd_addr_t *bdAddr)
|
||
{
|
||
unsigned char addr[BD_ADDR_LEN] = {0};
|
||
if (strncmp((const char *)g_bdAddr.addr, (const char *)addr, BD_ADDR_LEN) == 0) {
|
||
(void)memcpy_s(g_bdAddr.addr, BD_ADDR_LEN, bdAddr->addr, BD_ADDR_LEN);
|
||
}
|
||
}
|
||
|
||
static void HfpIncomingEventPublish(uint16 topic, hfp_hf_calls_info_t callsInfo)
|
||
{
|
||
int32_t ret;
|
||
uint32_t size = sizeof(hfp_hf_calls_info_t);
|
||
static_print_debug("HfpIncomingEventPublish topic=%u!!", topic);
|
||
|
||
TjdUiMsgEventPublish(topic, &callsInfo, size);
|
||
}
|
||
|
||
#pragma region 通话记录
|
||
// 获取当前通话记录
|
||
std::vector<CallLogInfo> ReadCallLogs(void)
|
||
{
|
||
std::vector<CallLogInfo> callLogs;
|
||
FILE *fp = fopen(TJD_CALL_LOG_PATH, "rb");
|
||
if (fp == nullptr) {
|
||
static_print_error("[ReadCallLogs] fopen %s failed!", TJD_CALL_LOG_PATH);
|
||
return callLogs;
|
||
}
|
||
|
||
CallLogInfo info;
|
||
while (fread(&info, sizeof(CallLogInfo), 1, fp) == 1) {
|
||
static_print_debug("[ReadCallLogs] name %s, tel %s", info.name, info.tel);
|
||
callLogs.push_back(info);
|
||
}
|
||
|
||
if (ferror(fp)) {
|
||
static_print_error("[ReadCallLogs] fread failed!");
|
||
}
|
||
|
||
fclose(fp);
|
||
return callLogs;
|
||
}
|
||
|
||
// 通话记录初始化
|
||
static void CallListInit(void)
|
||
{
|
||
int i;
|
||
g_currCallNum = 0;
|
||
(void)memset_s(g_callList, sizeof(g_callList), 0, sizeof(g_callList));
|
||
for (i = 0; i < MULTI_CALL_MAX_NUME; i++) {
|
||
(void)memset_s(g_callList[i].name, NAME_SIZE, '\0', NAME_SIZE);
|
||
(void)memset_s(g_callList[i].tel, MAX_PHONE_NUM, '\0', MAX_PHONE_NUM);
|
||
g_callList[i].lastStatus = HFP_HF_CALL_STATE_FINISHED;
|
||
}
|
||
}
|
||
|
||
// 获取通话记录文件大小
|
||
static int GetCallLogFileSize(void)
|
||
{
|
||
int len = 0;
|
||
FILE *fp = fopen(TJD_CALL_LOG_PATH, "rb");
|
||
if (fp == nullptr) {
|
||
static_print_error("[GetCallLogFileSize] fopen %s failed", TJD_CALL_LOG_PATH);
|
||
return 0;
|
||
}
|
||
|
||
fseek(fp, 0, SEEK_END);
|
||
len = ftell(fp);
|
||
fseek(fp, 0, SEEK_SET);
|
||
fclose(fp);
|
||
|
||
static_print_debug("[GetCallLogFileSize] len:%d", len);
|
||
return len;
|
||
}
|
||
|
||
// 清空通话记录
|
||
static int ClearCallLogInfoFile(void)
|
||
{
|
||
FILE *fp = fopen(TJD_CALL_LOG_PATH, "wb");
|
||
if (fp == nullptr) {
|
||
static_print_error("[ClearCallLogFile] fopen %s failed!", TJD_CALL_LOG_PATH);
|
||
return OHOS_FAILURE;
|
||
}
|
||
|
||
fclose(fp);
|
||
return OHOS_SUCCESS;
|
||
}
|
||
|
||
static ContactsInfo *FindCallInfoInCallList(const unsigned char *number, unsigned char numberLen)
|
||
{
|
||
int i;
|
||
const char *str1 = nullptr;
|
||
const char *str2 = nullptr;
|
||
if (g_currCallNum == 0) {
|
||
return nullptr;
|
||
}
|
||
for (i = 0; i < MULTI_CALL_MAX_NUME; i++) {
|
||
if (numberLen != g_callList[i].telLen) {
|
||
continue;
|
||
} else {
|
||
str1 = (const char *)number;
|
||
str2 = (const char *)g_callList[i].tel;
|
||
|
||
if (strncmp(str1, str2, numberLen) == 0) {
|
||
return &g_callList[i];
|
||
}
|
||
}
|
||
}
|
||
return nullptr;
|
||
}
|
||
|
||
// 通话记录添加
|
||
static void AddCurrCallToCallList(const hfp_hf_calls_info_t *call)
|
||
{
|
||
static_print_debug("[AddCurrCallToCallList] state:%d", call->state);
|
||
if (call == nullptr || g_currCallNum >= MULTI_CALL_MAX_NUME ||
|
||
(call->state != HFP_HF_CALL_STATE_ACTIVE && call->state != HFP_HF_CALL_STATE_HELD &&
|
||
call->state != HFP_HF_CALL_STATE_ALERTING)) {
|
||
return;
|
||
}
|
||
|
||
g_currCallNum++;
|
||
int32_t tmp = g_currCallNum - 1;
|
||
ContactsInfo *phoneCall = &g_callList[tmp];
|
||
if (call->state == HFP_HF_CALL_STATE_ACTIVE) { // 正在通话
|
||
phoneCall->operate = OPERATE_PHONE_ACTIVE;
|
||
phoneCall->activeTime = time(nullptr);
|
||
} else if (call->state == HFP_HF_CALL_STATE_HELD) { // 挂起
|
||
phoneCall->operate = OPERATE_PHONE_HOLD;
|
||
phoneCall->activeTime = time(nullptr);
|
||
} else if (call->state == HFP_HF_CALL_STATE_ALERTING) { // 呼出,对方响铃
|
||
phoneCall->operate = OPERATE_ALERTING;
|
||
}
|
||
|
||
// 使用通讯录接口获取当前电话对应的备注人名(通讯录待开发)
|
||
|
||
phoneCall->lastStatus = call->state;
|
||
phoneCall->creationTime = time(nullptr);
|
||
|
||
int32_t ret = memcpy_s(phoneCall->tel, MAX_PHONE_NUM, call->number, call->number_len);
|
||
if (ret != EOK) {
|
||
static_print_error("[AddCurrCallToCallList] copy tel ret:%d", ret);
|
||
}
|
||
phoneCall->telLen = call->number_len;
|
||
(void)memcpy_s(&phoneCall->unitCalls, sizeof(hfp_hf_calls_info_t), call, sizeof(hfp_hf_calls_info_t));
|
||
static_print_debug("[AddCurrCallToCallList] end");
|
||
|
||
static_print_debug("[AddCurrCallToCallList] name:%s, tel:%s, telLen:%d", phoneCall->name, phoneCall->tel,
|
||
phoneCall->telLen);
|
||
|
||
// 通知手表电话呼入
|
||
CallChangedCb(phoneCall);
|
||
}
|
||
|
||
static int CopyPhoneLogToTmpLog(void)
|
||
{
|
||
FILE *fp = nullptr;
|
||
FILE *ftp = nullptr;
|
||
CallLogInfo *info = nullptr;
|
||
|
||
int retLen;
|
||
int fileSize = GetCallLogFileSize();
|
||
if (fileSize == OHOS_FAILURE || fileSize == 0) {
|
||
return fileSize;
|
||
}
|
||
|
||
retLen = fileSize - sizeof(CallLogInfo);
|
||
if (retLen == 0) {
|
||
return ClearCallLogInfoFile(); // 只有一条记录,清空通话记录
|
||
}
|
||
|
||
fp = fopen(TJD_CALL_LOG_PATH, "rb");
|
||
if (fp == nullptr) {
|
||
return OHOS_FAILURE;
|
||
}
|
||
ftp = fopen(TJD_CALL_TMP_LOG_PATH, "wb+");
|
||
if (ftp == nullptr) {
|
||
fclose(fp);
|
||
return OHOS_FAILURE;
|
||
}
|
||
|
||
info = (CallLogInfo *)malloc(fileSize);
|
||
if (info == nullptr) {
|
||
fclose(fp);
|
||
fclose(ftp);
|
||
return OHOS_FAILURE;
|
||
}
|
||
|
||
(void)memset_s(info, fileSize, 0, fileSize);
|
||
if (fread(info, fileSize, 1, fp) != 1) {
|
||
retLen = OHOS_FAILURE;
|
||
goto END;
|
||
}
|
||
|
||
if (fwrite((info + 1), retLen, 1, ftp) != 1) {
|
||
retLen = OHOS_FAILURE;
|
||
goto END;
|
||
}
|
||
|
||
END:
|
||
fclose(fp);
|
||
fclose(ftp);
|
||
free(info);
|
||
info = nullptr;
|
||
return retLen;
|
||
}
|
||
|
||
// 删除第一条通话记录
|
||
static int RemoveFirstCallLog(void)
|
||
{
|
||
FILE *fp = nullptr;
|
||
FILE *ftp = nullptr;
|
||
CallLogInfo *info = nullptr;
|
||
|
||
int ret = OHOS_SUCCESS;
|
||
int fileSize = CopyPhoneLogToTmpLog();
|
||
if (fileSize == OHOS_FAILURE || fileSize == 0) {
|
||
return fileSize;
|
||
}
|
||
|
||
fp = fopen(TJD_CALL_LOG_PATH, "wb+");
|
||
if (fp == nullptr) {
|
||
return OHOS_FAILURE;
|
||
}
|
||
ftp = fopen(TJD_CALL_TMP_LOG_PATH, "rb");
|
||
if (ftp == nullptr) {
|
||
fclose(fp);
|
||
return OHOS_FAILURE;
|
||
}
|
||
|
||
info = (CallLogInfo *)malloc(fileSize);
|
||
if (info == nullptr) {
|
||
fclose(fp);
|
||
fclose(ftp);
|
||
return OHOS_FAILURE;
|
||
}
|
||
(void)memset_s(info, fileSize, 0, fileSize);
|
||
if (fread(info, fileSize, 1, ftp) != 1) {
|
||
ret = OHOS_FAILURE;
|
||
goto END;
|
||
}
|
||
|
||
if (fwrite(info, fileSize, 1, fp) != 1) {
|
||
ret = OHOS_FAILURE;
|
||
goto END;
|
||
}
|
||
|
||
END:
|
||
fclose(fp);
|
||
fclose(ftp);
|
||
free(info);
|
||
info = nullptr;
|
||
return ret;
|
||
}
|
||
|
||
static void AddToCallLog(CallLogInfo *info)
|
||
{
|
||
FILE *fp = nullptr;
|
||
size_t ret;
|
||
|
||
fp = fopen(TJD_CALL_LOG_PATH, "ab");
|
||
if (fp == nullptr) {
|
||
static_print_error("[AddToCallLog] fopen %s failed!", TJD_CALL_LOG_PATH);
|
||
return;
|
||
}
|
||
|
||
ret = fwrite(info, sizeof(CallLogInfo), 1, fp);
|
||
if (ret != 1) {
|
||
static_print_error("[AddToCallLog] fwrite failed! ret:%d", ret);
|
||
}
|
||
static_print_debug("[AddToCallLog] fwrite :%d", ret);
|
||
|
||
fclose(fp);
|
||
static_print_debug("[AddToCallLog] success! name:%s, tel:%s, telLen:%d", info->name, info->tel, info->telLen);
|
||
}
|
||
|
||
// 添加通话记录
|
||
static void AddToCallLogPro(ContactsInfo *callInfo)
|
||
{
|
||
if (callInfo == nullptr) {
|
||
return;
|
||
}
|
||
|
||
int fileSize = GetCallLogFileSize();
|
||
int num = fileSize / sizeof(CallLogInfo);
|
||
if (num >= CALL_LOG_MAX_NUM) {
|
||
int ret = RemoveFirstCallLog();
|
||
if (ret == OHOS_FAILURE) {
|
||
static_print_error("[AddToCallLogPro] RemoveFirstCallLog error");
|
||
return;
|
||
}
|
||
}
|
||
|
||
CallLogInfo info;
|
||
(void)memset_s(info.name, NAME_SIZE, '\0', NAME_SIZE);
|
||
(void)memset_s(info.tel, MAX_PHONE_NUM, '\0', MAX_PHONE_NUM);
|
||
int ret = memcpy_s(info.name, NAME_SIZE, callInfo->name, callInfo->nameLen);
|
||
if (ret != EOK) {
|
||
info.nameLen = 0;
|
||
} else {
|
||
info.nameLen = callInfo->nameLen;
|
||
}
|
||
|
||
ret = memcpy_s(info.tel, MAX_PHONE_NUM, callInfo->unitCalls.number, callInfo->unitCalls.number_len);
|
||
if (ret != EOK) {
|
||
info.telLen = 0;
|
||
} else {
|
||
info.telLen = callInfo->unitCalls.number_len;
|
||
}
|
||
|
||
info.creationTime = callInfo->creationTime;
|
||
if (callInfo->lastStatus == HFP_HF_CALL_STATE_ACTIVE || callInfo->lastStatus == HFP_HF_CALL_STATE_HELD ||
|
||
callInfo->lastStatus == HFP_HF_CALL_STATE_RESPONSE_HELD) {
|
||
info.callDurTime = time(nullptr) - callInfo->activeTime;
|
||
} else {
|
||
info.callDurTime = 0;
|
||
}
|
||
|
||
if (callInfo->lastStatus == HFP_HF_CALL_STATE_INCOMING || callInfo->lastStatus == HFP_HF_CALL_STATE_WAITING) {
|
||
info.status = CALL_MISSED;
|
||
} else if (callInfo->unitCalls.outgoing == 1) {
|
||
info.status = CALL_OUTGOING;
|
||
} else {
|
||
info.status = CALL_INCOMING;
|
||
}
|
||
|
||
AddToCallLog(&info);
|
||
}
|
||
|
||
#pragma endregion
|
||
|
||
static void BtDisconnectedPro(void)
|
||
{
|
||
g_btConnState = PROFILE_STATE_DISCONNECTED;
|
||
(void)memset_s(g_bdAddr.addr, BD_ADDR_LEN, 0, BD_ADDR_LEN);
|
||
|
||
// 通知APP蓝牙断开连接
|
||
PhoneServiceErrorCallback(ERROR_BT, PROFILE_STATE_DISCONNECTED);
|
||
CallListInit();
|
||
|
||
if (g_currCallState == HFP_HF_CALL_STATE_INCOMING) {
|
||
/* 处理呼入阶段,取消手表配对 */
|
||
hfp_hf_calls_info_t call = {};
|
||
HfpIncomingEventPublish(TOPIC_EVENT_HFP_FINISHED, call);
|
||
}
|
||
|
||
g_currCallState = HFP_HF_CALL_STATE_FINISHED;
|
||
g_scoFlag = HFP_SCO_STATE_DISCONNECTED;
|
||
g_completeCallFlag = false;
|
||
}
|
||
|
||
static bool IsCompleteCallFlow(void) { return g_completeCallFlag; }
|
||
|
||
// 获取当前通话音量大小 (0 - 15)
|
||
// hfp音量范围 0-15, media 音量范围 0-100
|
||
unsigned char GetHFPCallCurrVolume(void)
|
||
{
|
||
TjdPhoneAudio &audio = TjdPhoneAudio::GetInstance();
|
||
int32_t volume = audio.PhoneAudioGetVolume();
|
||
int32_t minVolume = audio.PhoneAudioGetMinVolume();
|
||
int32_t maxVolume = audio.PhoneAudioGetMaxVolume();
|
||
unsigned char hfpVolume = (unsigned char)((volume * CALL_VOLUME_MAX) / (maxVolume - minVolume)); // 转换
|
||
|
||
if (volume != 0 && hfpVolume == 0) {
|
||
hfpVolume = 1;
|
||
}
|
||
static_print_debug("[GetHFPCallCurrVolume] volume:%d, minVolume:%d, maxVolume:%d, hfpVolume:%d", volume, minVolume,
|
||
maxVolume, hfpVolume);
|
||
return hfpVolume;
|
||
}
|
||
|
||
void SetHFPSpeakerVolume(unsigned char hfpVolume)
|
||
{
|
||
TjdPhoneAudio &audio = TjdPhoneAudio::GetInstance();
|
||
static_print_debug("[SetHFPSpeakerVolume] start, hfpVolume:%d", hfpVolume);
|
||
int32_t minVolume = audio.PhoneAudioGetMinVolume();
|
||
int32_t maxVolume = audio.PhoneAudioGetMaxVolume();
|
||
int32_t volume = hfpVolume * (maxVolume - minVolume) / CALL_VOLUME_MAX; // 转换
|
||
static_print_debug("[SetHFPSpeakerVolume] minVolume:%d, maxVolume:%d, volume:%d", minVolume, maxVolume, volume);
|
||
int32_t ret = audio.PhoneAudioSetVolume(volume);
|
||
if (!ret) {
|
||
static_print_error("[SetHFPSpeakerVolume] PhoneAudioSetVolume ret:%d", ret);
|
||
return;
|
||
}
|
||
ret = hfp_hf_set_volume(&g_bdAddr, HFP_VOLUME_SPEAKER, hfpVolume);
|
||
if (ret != ERRCODE_BT_SUCCESS) {
|
||
static_print_error("[SetHFPSpeakerVolume] set_volume ret:%d, hfpVolume:%d", ret, hfpVolume);
|
||
return;
|
||
}
|
||
static_print_debug("[SetHFPSpeakerVolume] success!");
|
||
}
|
||
|
||
// 通话状态变化--接听流程处理
|
||
static void CallChangeActivePro(const hfp_hf_calls_info_t *call)
|
||
{
|
||
if (call == nullptr) {
|
||
return;
|
||
}
|
||
|
||
// 如果通话记录中没有该通话,添加到通话记录中,然后通知通话转移到手机
|
||
ContactsInfo *phoneCall = nullptr;
|
||
phoneCall = FindCallInfoInCallList((const unsigned char *)call->number, call->number_len);
|
||
if (phoneCall == nullptr) {
|
||
static_print_debug("[CallChangeActivePro] Active no this call");
|
||
AddCurrCallToCallList(call);
|
||
// TransCallToMobilePhone();
|
||
return;
|
||
}
|
||
|
||
if (phoneCall->lastStatus == HFP_HF_CALL_STATE_HELD && IsCompleteCallFlow()) { // 挂起状态切换到接听状态
|
||
phoneCall->operate = OPERATE_WATCH_ACTIVE;
|
||
} else if (phoneCall->lastStatus == HFP_HF_CALL_STATE_HELD && (!IsCompleteCallFlow())) {
|
||
phoneCall->operate = OPERATE_PHONE_ACTIVE;
|
||
} else if (phoneCall->operate == OPERATE_WATCH_ACTIVE) { // 手表接听
|
||
// 不做操作
|
||
} else {
|
||
if (phoneCall->unitCalls.outgoing == 1 && (phoneCall->lastStatus == HFP_HF_CALL_STATE_DIALING ||
|
||
phoneCall->lastStatus == HFP_HF_CALL_STATE_ALERTING)) {
|
||
phoneCall->operate = OPERATE_PEER_ACTIVE; // 对方接听
|
||
} else {
|
||
// 手机接听
|
||
phoneCall->operate = OPERATE_PHONE_ACTIVE;
|
||
static_print_debug("[CallChangeActivePro] phone active!");
|
||
}
|
||
}
|
||
|
||
if (phoneCall->activeTime == 0 &&
|
||
(phoneCall->lastStatus == HFP_HF_CALL_STATE_DIALING || phoneCall->lastStatus == HFP_HF_CALL_STATE_ALERTING ||
|
||
phoneCall->lastStatus == HFP_HF_CALL_STATE_INCOMING || phoneCall->lastStatus == HFP_HF_CALL_STATE_WAITING)) {
|
||
phoneCall->activeTime = time(nullptr);
|
||
}
|
||
|
||
phoneCall->lastStatus = call->state;
|
||
(void)memcpy_s(&phoneCall->unitCalls, sizeof(hfp_hf_calls_info_t), call, sizeof(hfp_hf_calls_info_t));
|
||
if (phoneCall->operate == OPERATE_PHONE_ACTIVE) {
|
||
// 发布电话接听事件,手表关闭来电通知
|
||
HfpIncomingEventPublish(TOPIC_EVENT_HFP_PHONE_ACTIVE, phoneCall->unitCalls);
|
||
} else if (phoneCall->operate == OPERATE_WATCH_ACTIVE && g_scoFlag == HFP_SCO_STATE_CONNECTED) {
|
||
// 发布手表接听事件,通知切换接听界面
|
||
HfpIncomingEventPublish(TOPIC_EVENT_HFP_WATCH_ACTIVE, phoneCall->unitCalls);
|
||
}
|
||
// 通知手表触发接听
|
||
CallChangedCb(phoneCall);
|
||
}
|
||
|
||
// 通话状态变化--挂起通话(当前只有手机挂起触发(并且手表不需感知),手表不支持挂起触发,对方挂起不感知)
|
||
static void CallChangeHeldPro(const hfp_hf_calls_info_t *call)
|
||
{
|
||
if (call == nullptr) {
|
||
return;
|
||
}
|
||
|
||
ContactsInfo *phoneCall = FindCallInfoInCallList((const unsigned char *)call->number, call->number_len);
|
||
if (phoneCall == nullptr) {
|
||
static_print_debug("[CallChangeHeldPro] Held no this call");
|
||
AddCurrCallToCallList(call);
|
||
return;
|
||
}
|
||
|
||
// 手机挂起通话
|
||
phoneCall->operate = OPERATE_PHONE_HOLD;
|
||
if (phoneCall->lastStatus == HFP_HF_CALL_STATE_INCOMING || phoneCall->lastStatus == HFP_HF_CALL_STATE_WAITING) {
|
||
phoneCall->activeTime = time(nullptr);
|
||
}
|
||
phoneCall->lastStatus = call->state;
|
||
(void)memcpy_s(&phoneCall->unitCalls, sizeof(hfp_hf_calls_info_t), call, sizeof(hfp_hf_calls_info_t));
|
||
|
||
// 通知手表触发挂起
|
||
CallChangedCb(phoneCall);
|
||
}
|
||
|
||
// 通话状态变化--呼出,正在拨号处理
|
||
static void CallChangeDialPro(const hfp_hf_calls_info_t *call)
|
||
{
|
||
if (call == nullptr) {
|
||
return;
|
||
}
|
||
|
||
g_currCallNum++;
|
||
int32_t tmp = g_currCallNum - 1;
|
||
ContactsInfo *phoneCall = &g_callList[tmp];
|
||
|
||
// 使用通讯录接口获取当前电话对应的备注人名(通讯录待开发)
|
||
|
||
phoneCall->operate = OPERATE_DIALING;
|
||
phoneCall->lastStatus = call->state;
|
||
phoneCall->creationTime = time(nullptr);
|
||
|
||
int32_t ret = memcpy_s(phoneCall->tel, MAX_PHONE_NUM, call->number, call->number_len);
|
||
if (ret != EOK) {
|
||
static_print_error("[CallChangeDialPro] copy tel ret:%d", ret);
|
||
}
|
||
phoneCall->telLen = call->number_len;
|
||
|
||
(void)memcpy_s(&phoneCall->unitCalls, sizeof(hfp_hf_calls_info_t), call, sizeof(hfp_hf_calls_info_t));
|
||
|
||
// 通知手表正在拨号
|
||
CallChangedCb(phoneCall);
|
||
}
|
||
|
||
// 通话状态变化--呼出,对方响铃
|
||
static void CallChangeAlertPro(const hfp_hf_calls_info_t *call)
|
||
{
|
||
ContactsInfo *phoneCall = nullptr;
|
||
if (call == nullptr) {
|
||
return;
|
||
}
|
||
phoneCall = FindCallInfoInCallList((const unsigned char *)call->number, call->number_len);
|
||
if (phoneCall == nullptr) {
|
||
static_print_debug("[CallChangeAlertPro] Alert no this call");
|
||
AddCurrCallToCallList(call);
|
||
return;
|
||
}
|
||
phoneCall->operate = OPERATE_ALERTING;
|
||
phoneCall->lastStatus = call->state;
|
||
|
||
(void)memcpy_s(&phoneCall->unitCalls, sizeof(hfp_hf_calls_info_t), call, sizeof(hfp_hf_calls_info_t));
|
||
|
||
// 通知手表正对方响铃
|
||
CallChangedCb(phoneCall);
|
||
}
|
||
|
||
// 通话状态变化--呼入处理
|
||
static void CallChangeIncomePro(const hfp_hf_calls_info_t *call)
|
||
{
|
||
if (call == nullptr || g_currCallNum >= MULTI_CALL_MAX_NUME ||
|
||
(call->state != HFP_HF_CALL_STATE_INCOMING && call->state != HFP_HF_CALL_STATE_WAITING)) {
|
||
return;
|
||
}
|
||
|
||
ContactsInfo *phoneCall = FindCallInfoInCallList((const unsigned char *)call->number, call->number_len);
|
||
if (phoneCall != nullptr) {
|
||
// 通话状态由呼入等待转换成呼入情况
|
||
} else {
|
||
g_currCallNum++;
|
||
int32_t tmp = g_currCallNum - 1;
|
||
phoneCall = &g_callList[tmp];
|
||
}
|
||
|
||
// 使用通讯录接口获取当前电话对应的备注人名(通讯录待开发)
|
||
|
||
if (call->state == HFP_HF_CALL_STATE_INCOMING) {
|
||
phoneCall->operate = OPERATE_INCOMING;
|
||
} else {
|
||
phoneCall->operate = OPERATE_WAITING;
|
||
}
|
||
phoneCall->lastStatus = call->state;
|
||
phoneCall->creationTime = time(nullptr);
|
||
|
||
int32_t ret = memcpy_s(phoneCall->tel, MAX_PHONE_NUM, call->number, call->number_len);
|
||
if (ret != EOK) {
|
||
static_print_error("[CallChangeIncomePro] copy tel ret:%d", ret);
|
||
}
|
||
phoneCall->telLen = call->number_len;
|
||
|
||
(void)memcpy_s(&phoneCall->unitCalls, sizeof(hfp_hf_calls_info_t), call, sizeof(hfp_hf_calls_info_t));
|
||
|
||
// 发布电话呼入事件
|
||
HfpIncomingEventPublish(TJDUI_TOPIC_EVENT_HFP_INCOMMING, phoneCall->unitCalls);
|
||
// 通知手表电话呼入
|
||
CallChangedCb(phoneCall);
|
||
}
|
||
|
||
// 通话状态变化--拒接/结束流程处理
|
||
static void CallChangeFinishPro(const hfp_hf_calls_info_t *call)
|
||
{
|
||
ContactsInfo *phoneCall = nullptr;
|
||
ContactsInfo tmp;
|
||
|
||
static_print_debug("[CallChangeFinishPro] start scoFlag:%d, CallNum:%d", g_scoFlag, g_currCallNum);
|
||
if (call == nullptr || g_currCallNum == 0) {
|
||
return;
|
||
}
|
||
|
||
phoneCall = FindCallInfoInCallList((const unsigned char *)call->number, call->number_len);
|
||
if (phoneCall == nullptr) {
|
||
static_print_debug("[CallChangeFinishPro] Finish no this call");
|
||
return;
|
||
}
|
||
if (g_finishOperate == OPERATE_WATCH_FINISH) {
|
||
phoneCall->operate = OPERATE_WATCH_FINISH;
|
||
} else if (g_finishOperate == OPERATE_WATCH_REJECT) {
|
||
phoneCall->operate = OPERATE_WATCH_REJECT;
|
||
} else {
|
||
phoneCall->operate = OPERATE_NON_WATCH_FINISH;
|
||
}
|
||
g_finishOperate = OPERATE_NON_WATCH_FINISH;
|
||
g_currCallNum--;
|
||
|
||
phoneCall->lastStatus = HFP_HF_CALL_STATE_FINISHED;
|
||
const ContactInfo *contactInfo = FindContactOfNumber((const unsigned char *)call->number, call->number_len);
|
||
if (contactInfo != nullptr) {
|
||
(void)memcpy_s(phoneCall->name, NAME_SIZE, contactInfo->name.c_str(), contactInfo->name.size());
|
||
}
|
||
|
||
(void)memcpy_s(&tmp, sizeof(ContactsInfo), phoneCall, sizeof(ContactsInfo));
|
||
(void)memcpy_s(&tmp.unitCalls, sizeof(hfp_hf_calls_info_t), call, sizeof(hfp_hf_calls_info_t));
|
||
(void)memset_s(phoneCall, sizeof(ContactsInfo), 0, sizeof(ContactsInfo));
|
||
(void)memset_s(phoneCall->name, NAME_SIZE, '\0', NAME_SIZE);
|
||
(void)memset_s(phoneCall->tel, MAX_PHONE_NUM, '\0', MAX_PHONE_NUM);
|
||
|
||
// 添加通话记录
|
||
AddToCallLogPro(&tmp);
|
||
|
||
// 发布电话结束事件
|
||
HfpIncomingEventPublish(TOPIC_EVENT_HFP_FINISHED, phoneCall->unitCalls);
|
||
// 通知手表通话结束
|
||
CallChangedCb(&tmp);
|
||
static_print_debug("[CallChangeFinishPro] end activeTime:%d, creation_time:%d", tmp.activeTime,
|
||
tmp.unitCalls.creation_time);
|
||
|
||
static_print_debug("[CallChangeFinishPro] end scoFlag:%d, CallNum:%d", g_scoFlag, g_currCallNum);
|
||
}
|
||
|
||
// 蓝牙状态连接
|
||
static void ConnStateChanged(const bd_addr_t *bdAddr, profile_connect_state_t state)
|
||
{
|
||
int ret = 0;
|
||
switch (state) {
|
||
case PROFILE_STATE_CONNECTING: // 蓝牙正在连接
|
||
static_print_debug("[ConnStateChanged] BT connecting");
|
||
break;
|
||
case PROFILE_STATE_CONNECTED: // 蓝牙连接成功
|
||
static_print_debug("[ConnStateChanged] BT connected");
|
||
g_btConnState = PROFILE_STATE_CONNECTED;
|
||
CopyBdAddr(bdAddr);
|
||
// SendMsgToUIService(BT_CONNECTED_TO_UI, 0, nullptr, 0);
|
||
// SendMsgToMsgCenterService(BT_CONNECTED_TO_MSGCENTER, 0, nullptr, 0);
|
||
break;
|
||
case PROFILE_STATE_DISCONNECTING: // 蓝牙连接断连
|
||
static_print_debug("[ConnStateChanged] BT disconnecting");
|
||
break;
|
||
case PROFILE_STATE_DISCONNECTED: // 蓝牙断开连接
|
||
static_print_debug("[ConnStateChanged] BT disconnected");
|
||
BtDisconnectedPro();
|
||
// SendMsgToUIService(BT_DISCONNECTED_TO_UI, 0, nullptr, 0);
|
||
// SendMsgToMsgCenterService(BT_DISCONNECTED_TO_MSGCENTER, 0, nullptr, 0);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 释放音频焦点
|
||
static void AudioDeactInterrupt(AudioStreamType type)
|
||
{
|
||
static_print_debug("[AudioDeactInterrupt] start type:0x%x, audioState:0x%x", type, g_audioState);
|
||
if ((type == AUDIO_STREAM_VOICE_CALL_BT_SCO && g_audioState >= AUDIO_ACT_INTERRUPT_BT_SCO) ||
|
||
(type == AUDIO_STREAM_RING && g_audioState == AUDIO_ACT_INTERRUPT_WATCH_RING)) {
|
||
TjdPhoneAudio::GetInstance().PhoneAudioManagerDeactInterrupt();
|
||
}
|
||
}
|
||
|
||
// 申请音频焦点
|
||
static void AudioActInterrupt(AudioStreamType type)
|
||
{
|
||
int ret = OHOS_SUCCESS;
|
||
static_print_debug("[AudioActInterrupt] start type:0x%x, audioState:0x%x", type, g_audioState);
|
||
if (type != AUDIO_STREAM_VOICE_CALL_BT_SCO && type != AUDIO_STREAM_RING) {
|
||
static_print_error("[AudioActInterrupt] failed! type:0x%x, audioState:0x%x", type, g_audioState);
|
||
return;
|
||
}
|
||
|
||
MUTEX_Lock(g_audioMutex);
|
||
// 申请蓝牙通话焦点
|
||
if (type == AUDIO_STREAM_VOICE_CALL_BT_SCO && g_audioState < AUDIO_ACT_INTERRUPT_BT_SCO) {
|
||
if (g_audioState == AUDIO_ACT_INTERRUPT_WATCH_RING) {
|
||
AudioDeactInterrupt(AUDIO_STREAM_RING);
|
||
}
|
||
|
||
ret = TjdPhoneAudio::GetInstance().PhoneAudioManagerActInterrupt(type);
|
||
if (ret == OHOS_SUCCESS) {
|
||
g_audioState = AUDIO_ACT_INTERRUPT_BT_SCO;
|
||
}
|
||
} else if (type == AUDIO_STREAM_RING && g_audioState < AUDIO_ACT_INTERRUPT_WATCH_RING) {
|
||
ret = TjdPhoneAudio::GetInstance().PhoneAudioManagerActInterrupt(type);
|
||
if (ret == OHOS_SUCCESS) {
|
||
g_audioState = AUDIO_ACT_INTERRUPT_WATCH_RING;
|
||
}
|
||
}
|
||
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioActInterrupt] failed! type:0x%x, audioState:0x%x", type, g_audioState);
|
||
}
|
||
|
||
MUTEX_Unlock(g_audioMutex);
|
||
}
|
||
|
||
// 媒体连接SCO设备
|
||
static void AudioConnectScoDevInit(void)
|
||
{
|
||
int ret;
|
||
TjdPhoneAudio &audio = TjdPhoneAudio::GetInstance();
|
||
static_print_debug("[AudioConnectScoDevInit] start scoFlag:0x%x, audioState:0x%x", g_scoFlag, g_audioState);
|
||
if (g_scoFlag != HFP_SCO_STATE_CONNECTED || g_audioState < AUDIO_ACT_INTERRUPT_BT_SCO) {
|
||
return;
|
||
}
|
||
|
||
MUTEX_Lock(g_audioMutex);
|
||
if (g_audioState < AUDIO_STREAM_INIT) {
|
||
if (g_audioState < AUDIO_CONN_IN_BT_SCO) {
|
||
// 配置媒体连接SCO设配状态(下行),只有在SCO连接后才能设置
|
||
ret = audio.PhoneAudioManagerSetDeviceConnState(IN_BLUETOOTH_SCO, AUDIO_DEVICE_CONNECTED);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioConnectScoDevInit] sco in ret:%d", ret);
|
||
MUTEX_Unlock(g_audioMutex);
|
||
return;
|
||
} else {
|
||
g_audioState = AUDIO_CONN_IN_BT_SCO;
|
||
}
|
||
}
|
||
if (g_audioState < AUDIO_CONN_OUT_BT_SCO) {
|
||
// 配置媒体连接SCO设配状态(上行),只有在SCO连接后才能设置
|
||
ret = audio.PhoneAudioManagerSetDeviceConnState(OUT_BLUETOOTH_SCO, AUDIO_DEVICE_CONNECTED);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioConnectScoDevInit] sco out ret:%d", ret);
|
||
MUTEX_Unlock(g_audioMutex);
|
||
return;
|
||
} else {
|
||
g_audioState = AUDIO_CONN_OUT_BT_SCO;
|
||
}
|
||
}
|
||
if (g_hdlUpSco == INVALID_PHONE_SERVICE_VALUE) {
|
||
g_hdlUpSco = audio.PhoneAudioStreamOutInit(AUDIO_UP_LINK);
|
||
}
|
||
if (g_hdlDnSco == INVALID_PHONE_SERVICE_VALUE) {
|
||
g_hdlDnSco = audio.PhoneAudioStreamInInit(AUDIO_DOWN_LINK);
|
||
}
|
||
if (g_hdlUpSco != INVALID_PHONE_SERVICE_VALUE && g_hdlDnSco != INVALID_PHONE_SERVICE_VALUE) {
|
||
g_audioState = AUDIO_STREAM_INIT;
|
||
}
|
||
}
|
||
static_print_debug("[AudioConnectScoDevInit] end audioState:%d, hdlUpSco:%d, hdlDnSco:%d", g_audioState, g_hdlUpSco,
|
||
g_hdlDnSco);
|
||
MUTEX_Unlock(g_audioMutex);
|
||
}
|
||
|
||
// 建立上行通路
|
||
static void AudioUpStart(void)
|
||
{
|
||
int ret = OHOS_SUCCESS;
|
||
TjdPhoneAudio &audio = TjdPhoneAudio::GetInstance();
|
||
uint32 micShmId = 0;
|
||
static_print_debug("[AudioUpStart] start scoFlag:%d, audioState:%d", g_scoFlag, g_audioState);
|
||
if (g_scoFlag != HFP_SCO_STATE_CONNECTED || g_audioState < AUDIO_STREAM_INIT) {
|
||
return;
|
||
}
|
||
MUTEX_Lock(g_audioMutex);
|
||
if (g_audioState < AUDIO_STREAM_START_UP) {
|
||
if (g_hdlUpMic == INVALID_PHONE_SERVICE_VALUE) {
|
||
g_hdlUpMic = audio.PhoneAudioStreamInInit(AUDIO_UP_LINK);
|
||
}
|
||
if (g_audioState < AUDIO_STREAM_START_SCO) {
|
||
ret = audio.PhoneAudioStreamInStart(g_hdlDnSco);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioUpStart] dn_sco ret:%d", ret);
|
||
}
|
||
ret |= audio.PhoneAudioStreamOutStart(g_hdlUpSco);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioUpStart] up_sco ret:%d", ret);
|
||
}
|
||
if (ret == OHOS_SUCCESS) {
|
||
g_audioState = AUDIO_STREAM_START_SCO;
|
||
}
|
||
}
|
||
|
||
ret |= audio.PhoneAudioStreamInStart(g_hdlUpMic);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioUpStart] up_mic ret:%d", ret);
|
||
}
|
||
|
||
ret |= audio.PhoneAudioStreamInGetChannelId(g_hdlUpMic, &micShmId);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioUpStart] up_mic shm ret:%d", ret);
|
||
}
|
||
|
||
ret |= audio.PhoneAudioStreamOutAttachFrontend(g_hdlUpSco, micShmId);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioUpStart] up_sco attach ret:%d", ret);
|
||
}
|
||
|
||
if (ret == OHOS_SUCCESS) {
|
||
g_audioState = AUDIO_STREAM_START_UP;
|
||
}
|
||
}
|
||
static_print_debug("[AudioUpStart] end audioState:%d, hdlUpMic:%d, hdlUpSco:%d, micShmId:0x%x", g_audioState,
|
||
g_hdlUpMic, g_hdlUpSco, micShmId);
|
||
MUTEX_Unlock(g_audioMutex);
|
||
}
|
||
|
||
// 建立下行通路
|
||
static void AudioDnStart(void)
|
||
{
|
||
int ret = OHOS_SUCCESS;
|
||
TjdPhoneAudio &audio = TjdPhoneAudio::GetInstance();
|
||
uint32 spkShmId = 0;
|
||
static_print_debug("[AudioDnStart] start scoFlag:%d, audioState:%d", g_scoFlag, g_audioState);
|
||
|
||
if (g_scoFlag != HFP_SCO_STATE_CONNECTED || g_audioState < AUDIO_STREAM_INIT) {
|
||
return;
|
||
}
|
||
MUTEX_Lock(g_audioMutex);
|
||
if (g_audioState < AUDIO_STREAM_START_DN) {
|
||
if (g_hdlDnSpk == INVALID_PHONE_SERVICE_VALUE) {
|
||
g_hdlDnSpk = audio.PhoneAudioStreamOutInit(AUDIO_DOWN_LINK);
|
||
}
|
||
if (g_audioState < AUDIO_STREAM_START_SCO) {
|
||
ret = audio.PhoneAudioStreamOutStart(g_hdlUpSco);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioDnStart] up_sco ret:%d", ret);
|
||
}
|
||
ret |= audio.PhoneAudioStreamInStart(g_hdlDnSco);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioDnStart] dn_sco ret:%d", ret);
|
||
}
|
||
if (ret == OHOS_SUCCESS) {
|
||
g_audioState = AUDIO_STREAM_START_SCO;
|
||
}
|
||
}
|
||
|
||
ret |= audio.PhoneAudioStreamOutStart(g_hdlDnSpk);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioDnStart] dn_spk ret:%d", ret);
|
||
}
|
||
ret |= audio.PhoneAudioStreamOutGetChannelId(g_hdlDnSpk, &spkShmId);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioDnStart] dn_spk shm ret:%d", ret);
|
||
}
|
||
ret |= audio.PhoneAudioStreamInAttachBackend(g_hdlDnSco, spkShmId);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioDnStart] dn_sco attach ret:%d", ret);
|
||
}
|
||
if (ret == OHOS_SUCCESS) {
|
||
g_audioState = AUDIO_STREAM_START_DN;
|
||
}
|
||
}
|
||
static_print_debug("[AudioDnStart] end audioState:%d, hdlDnSpk:%d, hdlDnSco:%d, spkShmId:0x%x", g_audioState,
|
||
g_hdlDnSpk, g_hdlDnSco, spkShmId);
|
||
MUTEX_Unlock(g_audioMutex);
|
||
}
|
||
|
||
// 同步音量
|
||
static void SyncVolume(void)
|
||
{
|
||
unsigned char volume;
|
||
volume = GetHFPCallCurrVolume();
|
||
SetHFPSpeakerVolume(volume);
|
||
}
|
||
|
||
// 蓝牙通话上行
|
||
static void AudioUp(void)
|
||
{
|
||
// 申请蓝牙通话音频焦点
|
||
AudioActInterrupt(AUDIO_STREAM_VOICE_CALL_BT_SCO);
|
||
// 媒体连接SCO设备
|
||
AudioConnectScoDevInit();
|
||
// 建立音频上行通路
|
||
AudioUpStart();
|
||
static_print_debug("[AudioUp] audioState:%d", g_audioState);
|
||
}
|
||
|
||
// 蓝牙通话下行
|
||
static void AudioDn(void)
|
||
{
|
||
AudioActInterrupt(AUDIO_STREAM_VOICE_CALL_BT_SCO);
|
||
|
||
// 媒体连接SCO设备
|
||
AudioConnectScoDevInit();
|
||
|
||
// 建立音频下行通路
|
||
AudioDnStart();
|
||
if (g_audioState == AUDIO_STREAM_START_DN) {
|
||
// 同步音量
|
||
SyncVolume();
|
||
}
|
||
static_print_debug("[AudioDn] audioState:%d", g_audioState);
|
||
}
|
||
|
||
static void AudioSetup(void)
|
||
{
|
||
if (g_audioState < AUDIO_STREAM_START_DN) {
|
||
AudioDn();
|
||
}
|
||
|
||
if (g_audioState != AUDIO_STREAM_START_UP) {
|
||
AudioUp();
|
||
}
|
||
}
|
||
|
||
static void PlayWatchRing(void) { static_print_debug("[PlayWatchRing] start"); }
|
||
|
||
static void AudioUpRelease(void)
|
||
{
|
||
int ret;
|
||
TjdPhoneAudio &audio = TjdPhoneAudio::GetInstance();
|
||
if (g_hdlUpSco != INVALID_PHONE_SERVICE_VALUE) {
|
||
ret = audio.PhoneAudioStreamOutStop(g_hdlUpSco);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioUpRelease] [OutStop] hdlUpSco ret:%d", ret);
|
||
}
|
||
ret = audio.PhoneAudioStreamOutDeinit(g_hdlUpSco);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioUpRelease] [OutDeinit] hdlUpSco ret:%d", ret);
|
||
}
|
||
}
|
||
|
||
if (g_hdlUpMic != INVALID_PHONE_SERVICE_VALUE) {
|
||
ret = audio.PhoneAudioStreamInStop(g_hdlUpMic);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioDnRelease] [InStop] hdlUpMic ret:%d", ret);
|
||
}
|
||
ret = audio.PhoneAudioStreamInDeinit(g_hdlUpMic);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioDnRelease] [InDeinit] hdlUpMic ret:%d", ret);
|
||
}
|
||
}
|
||
|
||
if (g_audioState >= AUDIO_CONN_OUT_BT_SCO) {
|
||
ret = audio.PhoneAudioManagerSetDeviceConnState(OUT_BLUETOOTH_SCO, AUDIO_DEVICE_DISCONNECTED);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioDnRelease] sco out ret:%d", ret);
|
||
}
|
||
}
|
||
|
||
g_hdlUpSco = INVALID_PHONE_SERVICE_VALUE;
|
||
g_hdlUpMic = INVALID_PHONE_SERVICE_VALUE;
|
||
}
|
||
|
||
static void AudioDnRelease(void)
|
||
{
|
||
int ret;
|
||
TjdPhoneAudio &audio = TjdPhoneAudio::GetInstance();
|
||
|
||
if (g_hdlDnSco != INVALID_PHONE_SERVICE_VALUE) {
|
||
ret = audio.PhoneAudioStreamInStop(g_hdlDnSco);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioUpRelease] [InStop] hdlDnSco ret:%d", ret);
|
||
}
|
||
ret = audio.PhoneAudioStreamInDeinit(g_hdlDnSco);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioUpRelease] [InDeinit] hdlDnSco ret:%d", ret);
|
||
}
|
||
}
|
||
|
||
if (g_hdlDnSpk != INVALID_PHONE_SERVICE_VALUE) {
|
||
ret = audio.PhoneAudioStreamOutStop(g_hdlDnSpk);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioDnRelease] [OutStop] hdlDnSpk ret:%d", ret);
|
||
}
|
||
ret = audio.PhoneAudioStreamOutDeinit(g_hdlDnSpk);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioDnRelease] [OutDeinit] hdlDnSpk ret:%d", ret);
|
||
}
|
||
}
|
||
|
||
if (g_audioState >= AUDIO_CONN_IN_BT_SCO) {
|
||
ret = audio.PhoneAudioManagerSetDeviceConnState(IN_BLUETOOTH_SCO, AUDIO_DEVICE_DISCONNECTED);
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioDnRelease] sco in ret:%d", ret);
|
||
}
|
||
}
|
||
|
||
g_hdlDnSco = INVALID_PHONE_SERVICE_VALUE;
|
||
g_hdlDnSpk = INVALID_PHONE_SERVICE_VALUE;
|
||
}
|
||
|
||
/* 销毁上下行通路 释放音频焦点 */
|
||
void AudioRelease(void)
|
||
{
|
||
if (g_audioState == AUDIO_UNKNOW) {
|
||
return;
|
||
}
|
||
|
||
MUTEX_Lock(g_audioMutex);
|
||
AudioUpRelease();
|
||
AudioDnRelease();
|
||
|
||
/* 释放音频焦点 */
|
||
AudioDeactInterrupt(AUDIO_STREAM_VOICE_CALL_BT_SCO);
|
||
AudioDeactInterrupt(AUDIO_STREAM_RING); // 适配某些机型不触发SCO
|
||
g_audioState = AUDIO_UNKNOW;
|
||
|
||
static_print_debug("[AudioRelease] audioState:%d,", g_audioState);
|
||
MUTEX_Unlock(g_audioMutex);
|
||
}
|
||
|
||
// SCO连接处理
|
||
static void ScoConnectPro(void)
|
||
{
|
||
// 通知sco建立连接(或通话转移:手机 -> 手表)
|
||
ScoStatusCb(HFP_SCO_STATE_CONNECTED);
|
||
if (g_currCallState == HFP_HF_CALL_STATE_ACTIVE && g_scoFlag == HFP_SCO_STATE_CONNECTED) {
|
||
// The call is transferred from the phone to the watch. Need to show the call notification view.
|
||
hfp_hf_calls_info_t call = {};
|
||
HfpIncomingEventPublish(TOPIC_EVENT_HFP_PHONE_TO_WATCH, call);
|
||
}
|
||
PostGraphicEvent(AudioSetup);
|
||
}
|
||
|
||
// SCO断连处理
|
||
static void ScoDisconnectPro(void)
|
||
{
|
||
static_print_debug("[ScoDisconnectPro] start CallState:%d", g_currCallState);
|
||
ScoStatusCb(HFP_SCO_STATE_DISCONNECTED);
|
||
if (g_currCallState == HFP_HF_CALL_STATE_ACTIVE && g_scoFlag == HFP_SCO_STATE_DISCONNECTED) {
|
||
// The call is transferred from the watch to the phone. Need to close the call notification view.
|
||
hfp_hf_calls_info_t call = {};
|
||
HfpIncomingEventPublish(TOPIC_EVENT_HFP_WATCH_TO_PHONE, call);
|
||
}
|
||
AudioRelease(); // 为了保持时序,此处采取同步调用
|
||
usleep(5000); // 增加延时确保SCO断开AUDIO通路释放成功
|
||
}
|
||
|
||
// Sco连接状态变化回调函数,音频连接状态
|
||
static void ScoStateChanged(const bd_addr_t *bdAddr, hfp_sco_connect_state_t state)
|
||
{
|
||
g_scoFlag = state;
|
||
static_print_debug("[ScoStateChanged] hfpState:%d, ScoFlag:%d, CallNum:%d", state, g_scoFlag, g_currCallNum);
|
||
|
||
switch (state) {
|
||
case HFP_SCO_STATE_CONNECTING:
|
||
PhoneServiceScreenCtr(1);
|
||
if (g_scoFlag != HFP_SCO_STATE_CONNECTED) {
|
||
g_scoFlag = HFP_SCO_STATE_CONNECTED;
|
||
CopyBdAddr(bdAddr);
|
||
ScoConnectPro();
|
||
static_print_debug("[ScoStateChanged] SCO connecting!");
|
||
}
|
||
break;
|
||
case HFP_SCO_STATE_CONNECTED:
|
||
static_print_debug("[ScoStateChanged] SCO connected!");
|
||
break;
|
||
|
||
case HFP_SCO_STATE_DISCONNECTING:
|
||
static_print_debug("[ScoStateChanged] SCO disconnecting!");
|
||
break;
|
||
|
||
case HFP_SCO_STATE_DISCONNECTED:
|
||
static_print_debug("[ScoStateChanged] SCO disconnected!");
|
||
ScoDisconnectPro();
|
||
PhoneServiceScreenCtr(0);
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
static void HfpBatteryChanged(const bd_addr_t *bdAddr, int batteryLevel)
|
||
{
|
||
UNUSED(bdAddr);
|
||
UNUSED(batteryLevel);
|
||
static_print_debug("[HfpBatteryChanged] batteryLevel:%d", batteryLevel);
|
||
}
|
||
|
||
static void HfpSignalStrengthChanged(const bd_addr_t *bdAddr, int signalStrength)
|
||
{
|
||
UNUSED(bdAddr);
|
||
UNUSED(signalStrength);
|
||
static_print_debug("[HfpSignalStrengthChanged] signalStrength:%d", signalStrength);
|
||
}
|
||
|
||
static void HfpRegistStatusChanged(const bd_addr_t *bdAddr, int status)
|
||
{
|
||
UNUSED(bdAddr);
|
||
UNUSED(status);
|
||
static_print_debug("[HfpRegistStatusChanged] status:%d", status);
|
||
}
|
||
|
||
static void HfpRoamingStatusChanged(const bd_addr_t *bdAddr, int status)
|
||
{
|
||
UNUSED(bdAddr);
|
||
UNUSED(status);
|
||
static_print_debug("[HfpRoamingStatusChanged] status:%d", status);
|
||
}
|
||
|
||
static void HfpOperatorSelection(const bd_addr_t *bdAddr, unsigned char *name, unsigned int len)
|
||
{
|
||
UNUSED(bdAddr);
|
||
UNUSED(name);
|
||
UNUSED(len);
|
||
static_print_debug("[HfpOperatorSelection] name: %s, len:%d", name, len);
|
||
}
|
||
|
||
static void HfpSubscriberNumber(const bd_addr_t *bdAddr, unsigned char *number, unsigned int len)
|
||
{
|
||
UNUSED(bdAddr);
|
||
UNUSED(number);
|
||
UNUSED(len);
|
||
static_print_debug("[HfpSubscriberNumber] number: %s, len:%d", number, len);
|
||
}
|
||
|
||
static void VoiceRecogStatusChanged(const bd_addr_t *bdAddr, int status)
|
||
{
|
||
UNUSED(bdAddr);
|
||
UNUSED(status);
|
||
static_print_debug("[VoiceRecogStatusChanged] status:%d", status);
|
||
}
|
||
|
||
static void InbandRingtoneChanged(const bd_addr_t *bdAddr, int status)
|
||
{
|
||
UNUSED(bdAddr);
|
||
UNUSED(status);
|
||
static_print_debug("[InbandRingtoneChanged] status:%d", status);
|
||
}
|
||
|
||
static void BtHfpVolumeChanged(int volumeType, unsigned char hfpVolume)
|
||
{
|
||
// mic
|
||
if (volumeType == HFP_VOLUME_MIC) {
|
||
static_print_debug("VolumeChanged Type:%d, hfpVolume:%d", volumeType, hfpVolume);
|
||
}
|
||
|
||
// speak
|
||
if (volumeType == HFP_VOLUME_SPEAKER) {
|
||
int32_t minVolume = TjdPhoneAudio::GetInstance().PhoneAudioGetMinVolume();
|
||
int32_t maxVolume = TjdPhoneAudio::GetInstance().PhoneAudioGetMaxVolume();
|
||
int32_t volume = hfpVolume * (maxVolume - minVolume) / CALL_VOLUME_MAX; // 转换
|
||
volume = (volume == 0) ? ((maxVolume - minVolume) / CALL_VOLUME_MAX) : volume;
|
||
bool ret = TjdPhoneAudio::GetInstance().PhoneAudioSetVolume(volume);
|
||
if (!ret) {
|
||
static_print_error("VolumeChanged Type:%d, ret:%d", volumeType, ret);
|
||
}
|
||
static_print_debug("VolumeChanged Type:%d, min:%d, max:%d volume:%d ret:%d", volumeType, minVolume, maxVolume,
|
||
volume, ret);
|
||
}
|
||
}
|
||
|
||
// 音量调节回调
|
||
static void VolumeChanged(const bd_addr_t *bdAddr, hfp_volume_type_t type, unsigned char volume)
|
||
{
|
||
UNUSED(bdAddr);
|
||
static_print_debug("[VolumeChanged] type:%d volume:%d", type, volume);
|
||
GraphicService::GetInstance()->PostGraphicEvent(std::bind(BtHfpVolumeChanged, type, volume));
|
||
}
|
||
|
||
// 设置完整通话标志
|
||
static void SetCompleteCallFlag(const hfp_hf_calls_info_t *call)
|
||
{
|
||
if (call->state == HFP_HF_CALL_STATE_INCOMING) { // 呼入
|
||
g_completeCallFlag = true;
|
||
} else if ((call->state == HFP_HF_CALL_STATE_DIALING || call->state == HFP_HF_CALL_STATE_ALERTING) &&
|
||
(g_currCallNum == 1 || g_currCallNum == 0)) // 正在拨号或对方响铃
|
||
{
|
||
g_completeCallFlag = true;
|
||
} else if (call->state == HFP_HF_CALL_STATE_ACTIVE) { // 正在通话
|
||
g_completeCallFlag = true;
|
||
}
|
||
}
|
||
|
||
static void CallAudioHandle(const hfp_hf_calls_info_t *call)
|
||
{
|
||
int state = call->state;
|
||
if (state == HFP_HF_CALL_STATE_INCOMING || state == HFP_HF_CALL_STATE_DIALING ||
|
||
state == HFP_HF_CALL_STATE_ALERTING) { // 电话呼入,支持播放手机铃声
|
||
if (call->in_band_ring) {
|
||
// 播放手机端铃声
|
||
PostGraphicEvent(AudioDn);
|
||
} else {
|
||
if (g_scoFlag != HFP_SCO_STATE_CONNECTED) {
|
||
// 播放手表铃声
|
||
PostGraphicEvent(PlayWatchRing);
|
||
}
|
||
}
|
||
} else if (state == HFP_HF_CALL_STATE_FINISHED) {
|
||
return;
|
||
} else if (g_scoFlag == HFP_SCO_STATE_CONNECTED) {
|
||
PostGraphicEvent(AudioSetup);
|
||
}
|
||
}
|
||
|
||
static void CallShakeHandle(const hfp_hf_calls_info_t *call)
|
||
{
|
||
int state = call->state;
|
||
static_print_debug("[CallShakeHandle] state:%d", state);
|
||
if (state == HFP_HF_CALL_STATE_INCOMING) { // 电话呼入,支持播放手机铃声
|
||
TJD::TjdUiSettingCenter::GetInstance().PhoneShakeEvent();
|
||
} else if (state == HFP_HF_CALL_STATE_FINISHED || state == HFP_HF_CALL_STATE_ACTIVE) {
|
||
TJD::TjdUiSettingCenter::GetInstance().ShakeEndEvent();
|
||
}
|
||
}
|
||
|
||
// 通话状态变化上报回调
|
||
static void CallStateChanged(const bd_addr_t *bdAddr, const hfp_hf_calls_info_t *call)
|
||
{
|
||
CopyBdAddr(bdAddr);
|
||
if (call == nullptr || g_btConnState != PROFILE_STATE_CONNECTED) {
|
||
static_print_error("call is null or BT disconnected connStatus: 0x%X", g_btConnState);
|
||
return;
|
||
}
|
||
|
||
SetCompleteCallFlag(call);
|
||
CallAudioHandle(call);
|
||
CallShakeHandle(call);
|
||
|
||
static_print_debug("CallStateChanged state:%d", call->state);
|
||
switch (call->state) {
|
||
case HFP_HF_CALL_STATE_ACTIVE: // 0正在通话
|
||
CallChangeActivePro(call);
|
||
break;
|
||
case HFP_HF_CALL_STATE_HELD: // 挂起
|
||
CallChangeHeldPro(call);
|
||
break;
|
||
case HFP_HF_CALL_STATE_DIALING: // 2呼出,正在拨号
|
||
PhoneServiceScreenCtr(1);
|
||
CallChangeDialPro(call);
|
||
break;
|
||
case HFP_HF_CALL_STATE_ALERTING: // 3呼出,对方响铃
|
||
PhoneServiceScreenCtr(1);
|
||
CallChangeAlertPro(call);
|
||
break;
|
||
case HFP_HF_CALL_STATE_INCOMING: // 呼入
|
||
PhoneServiceScreenCtr(1);
|
||
CallChangeIncomePro(call);
|
||
break;
|
||
case HFP_HF_CALL_STATE_WAITING: // 呼入等待
|
||
PhoneServiceScreenCtr(1);
|
||
CallChangeIncomePro(call);
|
||
break;
|
||
case HFP_HF_CALL_STATE_FINISHED: // 7拒接/结束电话
|
||
CallChangeFinishPro(call);
|
||
PhoneServiceScreenCtr(0);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
// 规避某些型号手机在电话呼入时重复断开和连接SCO
|
||
if (call->state == HFP_HF_CALL_STATE_FINISHED) {
|
||
if (g_currCallNum == 0) {
|
||
g_currCallState = HFP_HF_CALL_STATE_FINISHED;
|
||
}
|
||
} else {
|
||
g_currCallState = call->state;
|
||
}
|
||
|
||
if (g_currCallNum == 0) {
|
||
g_completeCallFlag = false;
|
||
}
|
||
}
|
||
|
||
// 拨号失败回调
|
||
static void DialErrorCode(const bd_addr_t *bdAddr, int code)
|
||
{
|
||
UNUSED(bdAddr);
|
||
static_print_debug("[DialErrorCode] code:%d", code);
|
||
PhoneServiceErrorCallback(ERROR_DIAL, code);
|
||
}
|
||
|
||
static void CodecChanged(const bd_addr_t *bdAddr, int codec)
|
||
{
|
||
UNUSED(bdAddr);
|
||
if (codec == HFP_HF_CODEC_ID_CVSD) {
|
||
g_call_codec = PCM;
|
||
} else if (codec == HFP_HF_CODEC_ID_MSBC) {
|
||
g_call_codec = mSBC;
|
||
}
|
||
static_print_debug("[CodecChanged] codec:%d, call_codec:%d", codec, g_call_codec);
|
||
}
|
||
|
||
static void RegisterHfpHfCallbacks(void)
|
||
{
|
||
static_print_debug("[RegisterHfpHfCallbacks]");
|
||
int ret;
|
||
hfp_hf_callbacks_t callbacks = {
|
||
ConnStateChanged, ScoStateChanged,
|
||
HfpBatteryChanged, HfpSignalStrengthChanged,
|
||
HfpRegistStatusChanged, HfpRoamingStatusChanged,
|
||
HfpOperatorSelection, HfpSubscriberNumber,
|
||
VoiceRecogStatusChanged, InbandRingtoneChanged,
|
||
VolumeChanged, CallStateChanged,
|
||
DialErrorCode, CodecChanged,
|
||
};
|
||
|
||
ret = hfp_hf_register_callbacks(&callbacks);
|
||
if (ret != 0) {
|
||
static_print_error("[RegisterHfpHfCallbacks] ret:%d", ret);
|
||
}
|
||
}
|
||
|
||
static void ContactsSyncEvent() { ContactsGetCase(); }
|
||
|
||
void TjdPhoneServiceInit(void)
|
||
{
|
||
static_print_debug("[PhoneServiceInit] start");
|
||
g_scoFlag = HFP_SCO_STATE_DISCONNECTED;
|
||
int32_t ret = TjdPhoneAudio::GetInstance().AudioInit();
|
||
if (ret != OHOS_SUCCESS) {
|
||
static_print_error("[AudioInit] failed!");
|
||
}
|
||
g_audioMutex = MUTEX_InitValue();
|
||
|
||
DIR *dir = nullptr;
|
||
dir = opendir(TJD_CALL_LOG_DIR);
|
||
if (dir == nullptr) {
|
||
mkdir(TJD_CALL_LOG_DIR, S_IREAD | S_IWRITE);
|
||
} else {
|
||
closedir(dir);
|
||
}
|
||
|
||
if (GetCallLogFileSize() == OHOS_FAILURE) { // 如果不存在文件,创建新文件
|
||
(void)ClearCallLogInfoFile();
|
||
}
|
||
(void)memset_s(g_bdAddr.addr, BD_ADDR_LEN, 0, BD_ADDR_LEN);
|
||
CallListInit();
|
||
ContactsGetCase();
|
||
tjd_service_bt_register_contacts_event(ContactsSyncEvent);
|
||
RegisterHfpHfCallbacks();
|
||
static_print_debug("[PhoneServiceInit] end");
|
||
}
|
||
|
||
uint32_t GetCallAudioCodec(void) { return g_call_codec; }
|