1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "av_receiver_engine_adapter.h"
17 
18 #include <dlfcn.h>
19 
20 #include "daudio_constants.h"
21 #include "daudio_errorcode.h"
22 #include "daudio_log.h"
23 #include "daudio_util.h"
24 
25 #undef DH_LOG_TAG
26 #define DH_LOG_TAG "AVTransReceiverAdapter"
27 
28 namespace OHOS {
29 namespace DistributedHardware {
30 constexpr int32_t WAIT_TIMEOUT_MS = 5000;
Initialize(IAVEngineProvider * providerPtr,const std::string & peerDevId)31 int32_t AVTransReceiverAdapter::Initialize(IAVEngineProvider *providerPtr, const std::string &peerDevId)
32 {
33     DHLOGI("Init av reveiver engine.");
34     if (initialized_.load()) {
35         return DH_SUCCESS;
36     }
37     CHECK_NULL_RETURN(providerPtr, ERR_DH_AUDIO_NULLPTR);
38     receiverEngine_ = providerPtr->CreateAVReceiverEngine(peerDevId);
39     CHECK_NULL_RETURN(receiverEngine_, ERR_DH_AUDIO_NULLPTR);
40     receiverEngine_->RegisterReceiverCallback(shared_from_this());
41     initialized_ = true;
42     return DH_SUCCESS;
43 }
44 
Release()45 int32_t AVTransReceiverAdapter::Release()
46 {
47     DHLOGI("Release av reveiver engine.");
48     if (receiverEngine_ != nullptr) {
49         int32_t ret = receiverEngine_->Release();
50         if (ret != DH_SUCCESS) {
51             DHLOGE("Release av receiver engine failed");
52         }
53     }
54     initialized_ = false;
55     receiverEngine_ = nullptr;
56     chnCreateSuccess_ = false;
57     return DH_SUCCESS;
58 }
59 
Start()60 int32_t AVTransReceiverAdapter::Start()
61 {
62     DHLOGI("Start av reveiver engine.");
63     CHECK_NULL_RETURN(receiverEngine_, ERR_DH_AUDIO_NULLPTR);
64     return receiverEngine_->Start();
65 }
66 
Stop()67 int32_t AVTransReceiverAdapter::Stop()
68 {
69     DHLOGI("Stop av reveiver engine.");
70     CHECK_NULL_RETURN(receiverEngine_, ERR_DH_AUDIO_NULLPTR);
71     return receiverEngine_->Stop();
72 }
73 
SetParameter(const AVTransTag & tag,const std::string & param)74 int32_t AVTransReceiverAdapter::SetParameter(const AVTransTag &tag, const std::string &param)
75 {
76     DHLOGI("Set parameter.");
77     CHECK_NULL_RETURN(receiverEngine_, ERR_DH_AUDIO_NULLPTR);
78     return receiverEngine_->SetParameter(tag, param);
79 }
80 
CreateControlChannel(const std::string & peerDevId)81 int32_t AVTransReceiverAdapter::CreateControlChannel(const std::string &peerDevId)
82 {
83     DHLOGI("Create control channel, peerDevId:%{public}s.", GetAnonyString(peerDevId).c_str());
84     if (chnCreateSuccess_.load()) {
85         DHLOGI("Receiver channel already created.");
86         return DH_SUCCESS;
87     }
88 
89     CHECK_NULL_RETURN(receiverEngine_, ERR_DH_AUDIO_NULLPTR);
90     std::vector<std::string> dstDevIds = {peerDevId};
91     int32_t ret = receiverEngine_->CreateControlChannel(dstDevIds,
92         ChannelAttribute{TransStrategy::LOW_LATANCY_STRATEGY});
93     if (ret != DH_SUCCESS) {
94         DHLOGE("Create av receiver channel failed, ret: %{public}d", ret);
95         return ERR_DH_AV_TRANS_CREATE_CHANNEL_FAILED;
96     }
97     ret = WaitForChannelCreated();
98     if (ret != DH_SUCCESS) {
99         DHLOGE("Wait create sender channel failed, ret: %{public}d", ret);
100         return ERR_DH_AV_TRANS_CREATE_CHANNEL_FAILED;
101     }
102     return DH_SUCCESS;
103 }
104 
SendMessageToRemote(const std::shared_ptr<AVTransMessage> & message)105 int32_t AVTransReceiverAdapter::SendMessageToRemote(const std::shared_ptr<AVTransMessage> &message)
106 {
107     DHLOGI("Send message to remote.");
108     CHECK_NULL_RETURN(receiverEngine_, ERR_DH_AUDIO_NULLPTR);
109     return receiverEngine_->SendMessage(message);
110 }
111 
RegisterAdapterCallback(const std::shared_ptr<AVReceiverAdapterCallback> & callback)112 int32_t AVTransReceiverAdapter::RegisterAdapterCallback(const std::shared_ptr<AVReceiverAdapterCallback> &callback)
113 {
114     DHLOGI("Register adapter callback.");
115     CHECK_NULL_RETURN(callback, ERR_DH_AUDIO_NULLPTR);
116     adapterCallback_ = callback;
117     return DH_SUCCESS;
118 }
119 
WaitForChannelCreated()120 int32_t AVTransReceiverAdapter::WaitForChannelCreated()
121 {
122     std::unique_lock<std::mutex> lock(chnCreatedMtx_);
123     auto status = chnCreatedCondVar_.wait_for(lock, std::chrono::milliseconds(WAIT_TIMEOUT_MS),
124         [this]() { return chnCreateSuccess_.load(); });
125     if (!status) {
126         DHLOGI("Wait timeout.");
127         return ERR_DH_AUDIO_SA_WAIT_TIMEOUT;
128     }
129     if (!chnCreateSuccess_.load()) {
130         DHLOGE("Create av receiver channel failed.");
131         return ERR_DH_AV_TRANS_CREATE_CHANNEL_FAILED;
132     }
133     return DH_SUCCESS;
134 }
135 
OnReceiverEvent(const AVTransEvent & event)136 int32_t AVTransReceiverAdapter::OnReceiverEvent(const AVTransEvent &event)
137 {
138     DHLOGI("On receive event, type: %{public}d", event.type);
139     switch (event.type) {
140         case EventType::EVENT_CHANNEL_OPEN_FAIL:
141         case EventType::EVENT_CHANNEL_OPENED: {
142             chnCreateSuccess_ = (event.type == EventType::EVENT_CHANNEL_OPENED);
143             chnCreatedCondVar_.notify_one();
144             break;
145         }
146         case EventType::EVENT_CHANNEL_CLOSED:
147         case EventType::EVENT_START_FAIL:
148         case EventType::EVENT_START_SUCCESS:
149         case EventType::EVENT_STOP_SUCCESS:
150         case EventType::EVENT_ENGINE_ERROR:
151         case EventType::EVENT_REMOTE_ERROR:
152             if (adapterCallback_ != nullptr) {
153                 DHLOGD("On receive event.");
154                 adapterCallback_->OnEngineEvent(event);
155             }
156             break;
157         default:
158             DHLOGE("Invaild event type.");
159             break;
160     }
161     return DH_SUCCESS;
162 }
163 
OnMessageReceived(const std::shared_ptr<AVTransMessage> & message)164 int32_t AVTransReceiverAdapter::OnMessageReceived(const std::shared_ptr<AVTransMessage> &message)
165 {
166     if (adapterCallback_ != nullptr) {
167         adapterCallback_->OnEngineMessage(message);
168     }
169     return DH_SUCCESS;
170 }
171 
OnDataAvailable(const std::shared_ptr<AVTransBuffer> & buffer)172 int32_t AVTransReceiverAdapter::OnDataAvailable(const std::shared_ptr<AVTransBuffer> &buffer)
173 {
174     if (adapterCallback_ != nullptr) {
175         adapterCallback_->OnEngineDataAvailable(buffer);
176     }
177     return DH_SUCCESS;
178 }
179 } // namespace DistributedHardware
180 } // namespace OHOS