150a07fd2Sopenharmony_ci/*
250a07fd2Sopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
350a07fd2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
450a07fd2Sopenharmony_ci * you may not use this file except in compliance with the License.
550a07fd2Sopenharmony_ci * You may obtain a copy of the License at
650a07fd2Sopenharmony_ci *
750a07fd2Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
850a07fd2Sopenharmony_ci *
950a07fd2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1050a07fd2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1150a07fd2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1250a07fd2Sopenharmony_ci * See the License for the specific language governing permissions and
1350a07fd2Sopenharmony_ci * limitations under the License.
1450a07fd2Sopenharmony_ci */
1550a07fd2Sopenharmony_ci
1650a07fd2Sopenharmony_ci#include "daudio_manager_callback.h"
1750a07fd2Sopenharmony_ci
1850a07fd2Sopenharmony_ci#include <string>
1950a07fd2Sopenharmony_ci#include <hdf_base.h>
2050a07fd2Sopenharmony_ci#include <cstdlib>
2150a07fd2Sopenharmony_ci#include "iservice_registry.h"
2250a07fd2Sopenharmony_ci#include "iservmgr_hdi.h"
2350a07fd2Sopenharmony_ci#include "iproxy_broker.h"
2450a07fd2Sopenharmony_ci
2550a07fd2Sopenharmony_ci#include "daudio_constants.h"
2650a07fd2Sopenharmony_ci#include "daudio_errorcode.h"
2750a07fd2Sopenharmony_ci#include "daudio_hdf_operate.h"
2850a07fd2Sopenharmony_ci#include "daudio_hdi_handler.h"
2950a07fd2Sopenharmony_ci#include "daudio_hitrace.h"
3050a07fd2Sopenharmony_ci#include "daudio_log.h"
3150a07fd2Sopenharmony_ci#include "daudio_util.h"
3250a07fd2Sopenharmony_ci
3350a07fd2Sopenharmony_ci#undef DH_LOG_TAG
3450a07fd2Sopenharmony_ci#define DH_LOG_TAG "DAudioHdiHandler"
3550a07fd2Sopenharmony_ci
3650a07fd2Sopenharmony_cinamespace OHOS {
3750a07fd2Sopenharmony_cinamespace DistributedHardware {
3850a07fd2Sopenharmony_ciIMPLEMENT_SINGLE_INSTANCE(DAudioHdiHandler);
3950a07fd2Sopenharmony_ci
4050a07fd2Sopenharmony_ciDAudioHdiHandler::DAudioHdiHandler()
4150a07fd2Sopenharmony_ci{
4250a07fd2Sopenharmony_ci    DHLOGD("Distributed audio hdi handler construct.");
4350a07fd2Sopenharmony_ci    audioHdiRecipient_ = new AudioHdiRecipient();
4450a07fd2Sopenharmony_ci}
4550a07fd2Sopenharmony_ci
4650a07fd2Sopenharmony_ciDAudioHdiHandler::~DAudioHdiHandler()
4750a07fd2Sopenharmony_ci{
4850a07fd2Sopenharmony_ci    DHLOGD("Distributed audio hdi handler deconstructed.");
4950a07fd2Sopenharmony_ci}
5050a07fd2Sopenharmony_ci
5150a07fd2Sopenharmony_ciint32_t DAudioHdiHandler::InitHdiHandler()
5250a07fd2Sopenharmony_ci{
5350a07fd2Sopenharmony_ci    DHLOGI("Init hdi handler.");
5450a07fd2Sopenharmony_ci    if (audioSrvHdf_ != nullptr) {
5550a07fd2Sopenharmony_ci        return DH_SUCCESS;
5650a07fd2Sopenharmony_ci    }
5750a07fd2Sopenharmony_ci
5850a07fd2Sopenharmony_ci    DHLOGD("Load hdf driver start.");
5950a07fd2Sopenharmony_ci    int32_t ret = DaudioHdfOperate::GetInstance().LoadDaudioHDFImpl();
6050a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
6150a07fd2Sopenharmony_ci        DHLOGE("Load hdf driver failed, ret: %{public}d", ret);
6250a07fd2Sopenharmony_ci        return ret;
6350a07fd2Sopenharmony_ci    }
6450a07fd2Sopenharmony_ci    DHLOGI("Load hdf driver end.");
6550a07fd2Sopenharmony_ci
6650a07fd2Sopenharmony_ci    audioSrvHdf_ = IDAudioManager::Get(HDF_AUDIO_SERVICE_NAME.c_str(), false);
6750a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(audioSrvHdf_, ERR_DH_AUDIO_NULLPTR);
6850a07fd2Sopenharmony_ci    remote_ = OHOS::HDI::hdi_objcast<IDAudioManager>(audioSrvHdf_);
6950a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(remote_, ERR_DH_AUDIO_NULLPTR);
7050a07fd2Sopenharmony_ci    remote_->AddDeathRecipient(audioHdiRecipient_);
7150a07fd2Sopenharmony_ci    DHLOGD("Init hdi handler success.");
7250a07fd2Sopenharmony_ci    return DH_SUCCESS;
7350a07fd2Sopenharmony_ci}
7450a07fd2Sopenharmony_ci
7550a07fd2Sopenharmony_ciint32_t DAudioHdiHandler::UninitHdiHandler()
7650a07fd2Sopenharmony_ci{
7750a07fd2Sopenharmony_ci    DHLOGI("Unload hdf driver start.");
7850a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(remote_, ERR_DH_AUDIO_NULLPTR);
7950a07fd2Sopenharmony_ci    remote_->RemoveDeathRecipient(audioHdiRecipient_);
8050a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(audioSrvHdf_, DH_SUCCESS);
8150a07fd2Sopenharmony_ci
8250a07fd2Sopenharmony_ci    int32_t ret = DaudioHdfOperate::GetInstance().UnLoadDaudioHDFImpl();
8350a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
8450a07fd2Sopenharmony_ci        DHLOGE("Unload hdf driver failed, ret: %{public}d", ret);
8550a07fd2Sopenharmony_ci        return ret;
8650a07fd2Sopenharmony_ci    }
8750a07fd2Sopenharmony_ci    DHLOGD("Uninit hdi handler success.");
8850a07fd2Sopenharmony_ci    return DH_SUCCESS;
8950a07fd2Sopenharmony_ci}
9050a07fd2Sopenharmony_ci
9150a07fd2Sopenharmony_ciint32_t DAudioHdiHandler::RegisterAudioDevice(const std::string &devId, const int32_t dhId,
9250a07fd2Sopenharmony_ci    const std::string &capability, const std::shared_ptr<IDAudioHdiCallback> &callbackObjParam)
9350a07fd2Sopenharmony_ci{
9450a07fd2Sopenharmony_ci    DHLOGI("Register audio device, adpname: %{public}s, dhId: %{public}d", GetAnonyString(devId).c_str(), dhId);
9550a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(audioSrvHdf_, ERR_DH_AUDIO_NULLPTR);
9650a07fd2Sopenharmony_ci    std::string searchKey;
9750a07fd2Sopenharmony_ci    switch (GetDevTypeByDHId(dhId)) {
9850a07fd2Sopenharmony_ci        case AUDIO_DEVICE_TYPE_SPEAKER:
9950a07fd2Sopenharmony_ci            searchKey = devId + "Speaker" + std::to_string(dhId);
10050a07fd2Sopenharmony_ci            break;
10150a07fd2Sopenharmony_ci        case AUDIO_DEVICE_TYPE_MIC:
10250a07fd2Sopenharmony_ci            searchKey = devId + "Mic" + std::to_string(dhId);
10350a07fd2Sopenharmony_ci            break;
10450a07fd2Sopenharmony_ci        case AUDIO_DEVICE_TYPE_UNKNOWN:
10550a07fd2Sopenharmony_ci        default:
10650a07fd2Sopenharmony_ci            DHLOGE("Unknown audio device.");
10750a07fd2Sopenharmony_ci            return ERR_DH_AUDIO_NOT_SUPPORT;
10850a07fd2Sopenharmony_ci    }
10950a07fd2Sopenharmony_ci    {
11050a07fd2Sopenharmony_ci        std::lock_guard<std::mutex> devLck(devMapMtx_);
11150a07fd2Sopenharmony_ci        auto call = mapAudioMgrCallback_.find(searchKey);
11250a07fd2Sopenharmony_ci        if (call == mapAudioMgrCallback_.end()) {
11350a07fd2Sopenharmony_ci            const sptr<DAudioManagerCallback> callbackptr(new DAudioManagerCallback(callbackObjParam));
11450a07fd2Sopenharmony_ci            mapAudioMgrCallback_.emplace(searchKey, callbackptr);
11550a07fd2Sopenharmony_ci        }
11650a07fd2Sopenharmony_ci        auto dhIds = mapAudioMgrDhIds_.find(devId);
11750a07fd2Sopenharmony_ci        if (dhIds != mapAudioMgrDhIds_.end()) {
11850a07fd2Sopenharmony_ci            dhIds->second.insert(dhId);
11950a07fd2Sopenharmony_ci        } else {
12050a07fd2Sopenharmony_ci            std::set<int32_t> newDhIds;
12150a07fd2Sopenharmony_ci            newDhIds.insert(dhId);
12250a07fd2Sopenharmony_ci            mapAudioMgrDhIds_.emplace(devId, newDhIds);
12350a07fd2Sopenharmony_ci        }
12450a07fd2Sopenharmony_ci    }
12550a07fd2Sopenharmony_ci
12650a07fd2Sopenharmony_ci    auto iter = mapAudioMgrCallback_.find(searchKey);
12750a07fd2Sopenharmony_ci    if (iter != mapAudioMgrCallback_.end()) {
12850a07fd2Sopenharmony_ci        int32_t res = audioSrvHdf_->RegisterAudioDevice(devId, dhId, capability, iter->second);
12950a07fd2Sopenharmony_ci        if (res != HDF_SUCCESS) {
13050a07fd2Sopenharmony_ci            DHLOGE("Call hdf proxy register failed, res: %{public}d", res);
13150a07fd2Sopenharmony_ci            return ERR_DH_AUDIO_HDI_CALL_FAILED;
13250a07fd2Sopenharmony_ci        }
13350a07fd2Sopenharmony_ci    }
13450a07fd2Sopenharmony_ci    return DH_SUCCESS;
13550a07fd2Sopenharmony_ci}
13650a07fd2Sopenharmony_ci
13750a07fd2Sopenharmony_ciint32_t DAudioHdiHandler::UnRegisterAudioDevice(const std::string &devId, const int32_t dhId)
13850a07fd2Sopenharmony_ci{
13950a07fd2Sopenharmony_ci    DHLOGI("Unregister audio device, adpname: %{public}s, dhId: %{public}d", GetAnonyString(devId).c_str(), dhId);
14050a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(audioSrvHdf_, ERR_DH_AUDIO_NULLPTR);
14150a07fd2Sopenharmony_ci    int32_t res = audioSrvHdf_->UnRegisterAudioDevice(devId, dhId);
14250a07fd2Sopenharmony_ci    if (res != HDF_SUCCESS) {
14350a07fd2Sopenharmony_ci        DHLOGE("Call hdf proxy unregister failed, res: %{public}d", res);
14450a07fd2Sopenharmony_ci        return ERR_DH_AUDIO_HDI_CALL_FAILED;
14550a07fd2Sopenharmony_ci    }
14650a07fd2Sopenharmony_ci
14750a07fd2Sopenharmony_ci    {
14850a07fd2Sopenharmony_ci        std::lock_guard<std::mutex> devLck(devMapMtx_);
14950a07fd2Sopenharmony_ci        auto iter = mapAudioMgrDhIds_.find(devId);
15050a07fd2Sopenharmony_ci        if (iter == mapAudioMgrDhIds_.end()) {
15150a07fd2Sopenharmony_ci            DHLOGE("Can not find register devId. devId: %{public}s", GetAnonyString(devId).c_str());
15250a07fd2Sopenharmony_ci            return ERR_DH_AUDIO_SA_CALLBACK_NOT_FOUND;
15350a07fd2Sopenharmony_ci        }
15450a07fd2Sopenharmony_ci
15550a07fd2Sopenharmony_ci        iter->second.erase(dhId);
15650a07fd2Sopenharmony_ci        if (iter->second.empty()) {
15750a07fd2Sopenharmony_ci            mapAudioMgrDhIds_.erase(devId);
15850a07fd2Sopenharmony_ci        }
15950a07fd2Sopenharmony_ci    }
16050a07fd2Sopenharmony_ci    return DH_SUCCESS;
16150a07fd2Sopenharmony_ci}
16250a07fd2Sopenharmony_ci
16350a07fd2Sopenharmony_civoid DAudioHdiHandler::ProcessEventMsg(const AudioEvent &audioEvent, DAudioEvent &newEvent)
16450a07fd2Sopenharmony_ci{
16550a07fd2Sopenharmony_ci    switch (audioEvent.type) {
16650a07fd2Sopenharmony_ci        case AudioEventType::NOTIFY_OPEN_SPEAKER_RESULT:
16750a07fd2Sopenharmony_ci            newEvent.type = AUDIO_EVENT_OPEN_SPK_RESULT;
16850a07fd2Sopenharmony_ci            break;
16950a07fd2Sopenharmony_ci        case AudioEventType::NOTIFY_CLOSE_SPEAKER_RESULT:
17050a07fd2Sopenharmony_ci            newEvent.type = AUDIO_EVENT_CLOSE_SPK_RESULT;
17150a07fd2Sopenharmony_ci            break;
17250a07fd2Sopenharmony_ci        case AudioEventType::NOTIFY_OPEN_MIC_RESULT:
17350a07fd2Sopenharmony_ci            newEvent.type = AUDIO_EVENT_OPEN_MIC_RESULT;
17450a07fd2Sopenharmony_ci            break;
17550a07fd2Sopenharmony_ci        case AudioEventType::NOTIFY_CLOSE_MIC_RESULT:
17650a07fd2Sopenharmony_ci            newEvent.type = AUDIO_EVENT_CLOSE_MIC_RESULT;
17750a07fd2Sopenharmony_ci            break;
17850a07fd2Sopenharmony_ci        case AudioEventType::VOLUME_CHANGE:
17950a07fd2Sopenharmony_ci            newEvent.type = AUDIO_EVENT_VOLUME_CHANGE;
18050a07fd2Sopenharmony_ci            break;
18150a07fd2Sopenharmony_ci        case AudioEventType::SPEAKER_CLOSED:
18250a07fd2Sopenharmony_ci            newEvent.type = AUDIO_EVENT_SPK_CLOSED;
18350a07fd2Sopenharmony_ci            break;
18450a07fd2Sopenharmony_ci        case AudioEventType::MIC_CLOSED:
18550a07fd2Sopenharmony_ci            newEvent.type = AUDIO_EVENT_MIC_CLOSED;
18650a07fd2Sopenharmony_ci            break;
18750a07fd2Sopenharmony_ci        case AudioEventType::AUDIO_FOCUS_CHANGE:
18850a07fd2Sopenharmony_ci            newEvent.type = AUDIO_EVENT_FOCUS_CHANGE;
18950a07fd2Sopenharmony_ci            break;
19050a07fd2Sopenharmony_ci        case AudioEventType::AUDIO_RENDER_STATE_CHANGE:
19150a07fd2Sopenharmony_ci            newEvent.type = AUDIO_EVENT_RENDER_STATE_CHANGE;
19250a07fd2Sopenharmony_ci            break;
19350a07fd2Sopenharmony_ci        case AudioEventType::NOTIFY_HDF_SPK_DUMP:
19450a07fd2Sopenharmony_ci            newEvent.type = AUDIO_EVENT_SPK_DUMP;
19550a07fd2Sopenharmony_ci            break;
19650a07fd2Sopenharmony_ci        case AudioEventType::NOTIFY_HDF_MIC_DUMP:
19750a07fd2Sopenharmony_ci            newEvent.type = AUDIO_EVENT_MIC_DUMP;
19850a07fd2Sopenharmony_ci            break;
19950a07fd2Sopenharmony_ci        default:
20050a07fd2Sopenharmony_ci            DHLOGE("Unsupport audio event.");
20150a07fd2Sopenharmony_ci            break;
20250a07fd2Sopenharmony_ci    }
20350a07fd2Sopenharmony_ci}
20450a07fd2Sopenharmony_ci
20550a07fd2Sopenharmony_ciint32_t DAudioHdiHandler::NotifyEvent(const std::string &devId, const int32_t dhId,
20650a07fd2Sopenharmony_ci    const int32_t streamId, const AudioEvent &audioEvent)
20750a07fd2Sopenharmony_ci{
20850a07fd2Sopenharmony_ci    DHLOGD("Notify event adpname: %{public}s, dhId: %{public}d, event type: %{public}d, event content: %{public}s.",
20950a07fd2Sopenharmony_ci        GetAnonyString(devId).c_str(), dhId, audioEvent.type, audioEvent.content.c_str());
21050a07fd2Sopenharmony_ci    DAudioEvent newEvent = {AUDIO_EVENT_UNKNOWN, audioEvent.content};
21150a07fd2Sopenharmony_ci    ProcessEventMsg(audioEvent, newEvent);
21250a07fd2Sopenharmony_ci
21350a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(audioSrvHdf_, ERR_DH_AUDIO_NULLPTR);
21450a07fd2Sopenharmony_ci    if (audioSrvHdf_->NotifyEvent(devId, dhId, streamId, newEvent) != HDF_SUCCESS) {
21550a07fd2Sopenharmony_ci        DHLOGE("Call hdf proxy NotifyEvent failed.");
21650a07fd2Sopenharmony_ci        return ERR_DH_AUDIO_HDI_CALL_FAILED;
21750a07fd2Sopenharmony_ci    }
21850a07fd2Sopenharmony_ci    return DH_SUCCESS;
21950a07fd2Sopenharmony_ci}
22050a07fd2Sopenharmony_ci
22150a07fd2Sopenharmony_civoid DAudioHdiHandler::AudioHdiRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
22250a07fd2Sopenharmony_ci{
22350a07fd2Sopenharmony_ci    DHLOGE("Exit the current process remote died.");
22450a07fd2Sopenharmony_ci    _Exit(0);
22550a07fd2Sopenharmony_ci}
22650a07fd2Sopenharmony_ci} // namespace DistributedHardware
22750a07fd2Sopenharmony_ci} // namespace OHOS
228