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_sender_engine_adapter.h"
17 #include <dlfcn.h>
18 
19 #include "daudio_constants.h"
20 #include "daudio_errorcode.h"
21 #include "daudio_log.h"
22 #include "daudio_util.h"
23 
24 #include "av_trans_types.h"
25 
26 #undef DH_LOG_TAG
27 #define DH_LOG_TAG "AVTransSenderAdapter"
28 
29 namespace OHOS {
30 namespace DistributedHardware {
31 constexpr int32_t WAIT_TIMEOUT_MS = 5000;
32 
Initialize(IAVEngineProvider * providerPtr,const std::string & peerDevId)33 int32_t AVTransSenderAdapter::Initialize(IAVEngineProvider *providerPtr, const std::string &peerDevId)
34 {
35     DHLOGI("Init av sender engine.");
36     CHECK_NULL_RETURN(providerPtr, ERR_DH_AUDIO_NULLPTR);
37     if (initialized_.load()) {
38         return DH_SUCCESS;
39     }
40 
41     senderEngine_ = providerPtr->CreateAVSenderEngine(peerDevId);
42     CHECK_NULL_RETURN(senderEngine_, ERR_DH_AUDIO_NULLPTR);
43     senderEngine_->RegisterSenderCallback(shared_from_this());
44     initialized_ = true;
45     return DH_SUCCESS;
46 }
47 
Release()48 int32_t AVTransSenderAdapter::Release()
49 {
50     DHLOGI("Release av sender engine.");
51     if (senderEngine_ != nullptr) {
52         if (senderEngine_->Release() != DH_SUCCESS) {
53             DHLOGE("Release av sender engine failed");
54         }
55     }
56     initialized_ = false;
57     senderEngine_ = nullptr;
58     chnCreateSuccess_ = false;
59     return DH_SUCCESS;
60 }
61 
Start()62 int32_t AVTransSenderAdapter::Start()
63 {
64     DHLOGI("Start av sender engine.");
65     CHECK_NULL_RETURN(senderEngine_, ERR_DH_AUDIO_NULLPTR);
66     return senderEngine_->Start();
67 }
68 
Stop()69 int32_t AVTransSenderAdapter::Stop()
70 {
71     DHLOGI("Stop av sender engine.");
72     CHECK_NULL_RETURN(senderEngine_, ERR_DH_AUDIO_NULLPTR);
73     return senderEngine_->Stop();
74 }
75 
CreateControlChannel(const std::string & peerDevId)76 int32_t AVTransSenderAdapter::CreateControlChannel(const std::string &peerDevId)
77 {
78     DHLOGI("Create control channel,peerDevId:%{public}s", GetAnonyString(peerDevId).c_str());
79     if (chnCreateSuccess_.load()) {
80         DHLOGI("Channel already created.");
81         return DH_SUCCESS;
82     }
83 
84     CHECK_NULL_RETURN(senderEngine_, ERR_DH_AUDIO_NULLPTR);
85     std::vector<std::string> dstDevIds = {peerDevId};
86     int32_t ret = senderEngine_->CreateControlChannel(dstDevIds,
87         ChannelAttribute{TransStrategy::LOW_LATANCY_STRATEGY});
88     if (ret != DH_SUCCESS) {
89         DHLOGE("Create control channel failed, ret: %{public}d", ret);
90         return ERR_DH_AV_TRANS_CREATE_CHANNEL_FAILED;
91     }
92     ret = WaitForChannelCreated();
93     if (ret != DH_SUCCESS) {
94         DHLOGE("Wait for create av transport sender channel failed ret: %{public}d", ret);
95         return ERR_DH_AV_TRANS_CREATE_CHANNEL_FAILED;
96     }
97     return DH_SUCCESS;
98 }
99 
SetParameter(const AVTransTag & tag,const std::string & param)100 int32_t AVTransSenderAdapter::SetParameter(const AVTransTag &tag, const std::string &param)
101 {
102     DHLOGI("Set audio param.");
103     CHECK_NULL_RETURN(senderEngine_, ERR_DH_AUDIO_NULLPTR);
104     return senderEngine_->SetParameter(tag, param);
105 }
106 
PushData(std::shared_ptr<AudioData> & audioData)107 int32_t AVTransSenderAdapter::PushData(std::shared_ptr<AudioData> &audioData)
108 {
109     CHECK_NULL_RETURN(senderEngine_, ERR_DH_AUDIO_NULLPTR);
110     auto transBuffer = std::make_shared<AVTransBuffer>(MetaType::AUDIO);
111     auto bufferData = transBuffer->CreateBufferData(audioData->Size());
112     CHECK_NULL_RETURN(bufferData, ERR_DH_AUDIO_NULLPTR);
113 
114     bufferData->Write(audioData->Data(), audioData->Size());
115     return senderEngine_->PushData(transBuffer);
116 }
117 
SendMessageToRemote(const std::shared_ptr<AVTransMessage> & message)118 int32_t AVTransSenderAdapter::SendMessageToRemote(const std::shared_ptr<AVTransMessage> &message)
119 {
120     DHLOGI("Send message to remote.");
121     CHECK_NULL_RETURN(senderEngine_, ERR_DH_AUDIO_NULLPTR);
122     return senderEngine_->SendMessage(message);
123 }
124 
RegisterAdapterCallback(const std::shared_ptr<AVSenderAdapterCallback> & callback)125 int32_t AVTransSenderAdapter::RegisterAdapterCallback(const std::shared_ptr<AVSenderAdapterCallback> &callback)
126 {
127     DHLOGI("Register adapter callback.");
128     CHECK_NULL_RETURN(callback, ERR_DH_AUDIO_NULLPTR);
129     adapterCallback_ = callback;
130     return DH_SUCCESS;
131 }
132 
WaitForChannelCreated()133 int32_t AVTransSenderAdapter::WaitForChannelCreated()
134 {
135     std::unique_lock<std::mutex> lock(chnCreatedMtx_);
136     auto status = chnCreatedCondVar_.wait_for(lock, std::chrono::milliseconds(WAIT_TIMEOUT_MS),
137         [this]() { return chnCreateSuccess_.load(); });
138     if (!status) {
139         DHLOGI("Wait timeout.");
140         return ERR_DH_AUDIO_SA_WAIT_TIMEOUT;
141     }
142     if (!chnCreateSuccess_.load()) {
143         DHLOGE("Create av sender channel failed.");
144         return ERR_DH_AV_TRANS_CREATE_CHANNEL_FAILED;
145     }
146     return DH_SUCCESS;
147 }
148 
OnSenderEvent(const AVTransEvent & event)149 int32_t AVTransSenderAdapter::OnSenderEvent(const AVTransEvent &event)
150 {
151     DHLOGI("On sender event, type: %{public}d", event.type);
152     switch (event.type) {
153         case EventType::EVENT_CHANNEL_OPEN_FAIL:
154         case EventType::EVENT_CHANNEL_OPENED: {
155             chnCreateSuccess_ = (event.type == EventType::EVENT_CHANNEL_OPENED);
156             chnCreatedCondVar_.notify_one();
157             break;
158         }
159         case EventType::EVENT_CHANNEL_CLOSED:
160         case EventType::EVENT_START_FAIL:
161         case EventType::EVENT_START_SUCCESS:
162         case EventType::EVENT_STOP_SUCCESS:
163         case EventType::EVENT_ENGINE_ERROR:
164         case EventType::EVENT_REMOTE_ERROR:
165             if (adapterCallback_ != nullptr) {
166                 DHLOGI("Send event.");
167                 adapterCallback_->OnEngineEvent(event);
168             }
169             break;
170         default:
171             DHLOGE("Invaild event type.");
172             break;
173     }
174     return DH_SUCCESS;
175 }
176 
OnMessageReceived(const std::shared_ptr<AVTransMessage> & message)177 int32_t AVTransSenderAdapter::OnMessageReceived(const std::shared_ptr<AVTransMessage> &message)
178 {
179     if (adapterCallback_ != nullptr) {
180         adapterCallback_->OnEngineMessage(message);
181     }
182     return DH_SUCCESS;
183 }
184 } // namespace DistributedHardware
185 } // namespace OHOS