1 /*
2 * Copyright (c) 2022-2024 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 "daudio_sink_handler.h"
17
18 #include "if_system_ability_manager.h"
19 #include "iservice_registry.h"
20
21 #include "daudio_constants.h"
22 #include "daudio_errorcode.h"
23 #include "daudio_hisysevent.h"
24 #include "daudio_hitrace.h"
25 #include "daudio_log.h"
26 #include "daudio_sink_load_callback.h"
27 #include "daudio_util.h"
28
29 #undef DH_LOG_TAG
30 #define DH_LOG_TAG "DAudioSinkHandler"
31
32 namespace OHOS {
33 namespace DistributedHardware {
34 IMPLEMENT_SINGLE_INSTANCE(DAudioSinkHandler);
35
DAudioSinkHandler()36 DAudioSinkHandler::DAudioSinkHandler()
37 {
38 DHLOGD("DAudio sink handler constructed.");
39 if (!sinkSvrRecipient_) {
40 sinkSvrRecipient_ = sptr<DAudioSinkSvrRecipient>(new DAudioSinkSvrRecipient());
41 }
42 if (!dAudioSinkIpcCallback_) {
43 dAudioSinkIpcCallback_ = sptr<DAudioSinkIpcCallback>(new DAudioSinkIpcCallback());
44 }
45 }
46
~DAudioSinkHandler()47 DAudioSinkHandler::~DAudioSinkHandler()
48 {
49 DHLOGD("DAudio sink handler destructed.");
50 }
51
InitSink(const std::string & params)52 int32_t DAudioSinkHandler::InitSink(const std::string ¶ms)
53 {
54 DHLOGI("Init sink handler.");
55 if (dAudioSinkProxy_ == nullptr) {
56 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
57 CHECK_NULL_RETURN(samgr, ERR_DH_AUDIO_NULLPTR);
58 sptr<DAudioSinkLoadCallback> loadCallback(new DAudioSinkLoadCallback(params));
59 int32_t ret = samgr->LoadSystemAbility(DISTRIBUTED_HARDWARE_AUDIO_SINK_SA_ID, loadCallback);
60 if (ret != ERR_OK) {
61 DHLOGE("Failed to Load systemAbility ret code: %{public}d.", ret);
62 DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_INIT_FAIL, DISTRIBUTED_HARDWARE_AUDIO_SINK_SA_ID,
63 ERR_DH_AUDIO_SA_LOAD_FAILED, "daudio sink LoadSystemAbility call failed.");
64 return ERR_DH_AUDIO_SA_LOAD_FAILED;
65 }
66 }
67
68 std::unique_lock<std::mutex> lock(sinkProxyMutex_);
69 auto waitStatus = sinkProxyConVar_.wait_for(lock, std::chrono::milliseconds(AUDIO_LOADSA_TIMEOUT_MS),
70 [this]() { return dAudioSinkProxy_ != nullptr; });
71 if (!waitStatus) {
72 DHLOGE("Audio load sa timeout.");
73 DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_INIT_FAIL, DISTRIBUTED_HARDWARE_AUDIO_SINK_SA_ID,
74 ERR_DH_AUDIO_SA_LOAD_FAILED, "daudio sink sa load timeout.");
75 return ERR_DH_AUDIO_SA_LOAD_FAILED;
76 }
77 return DH_SUCCESS;
78 }
79
ReleaseSink()80 int32_t DAudioSinkHandler::ReleaseSink()
81 {
82 DHLOGI("Release sink handler.");
83 std::lock_guard<std::mutex> lock(sinkProxyMutex_);
84 if (dAudioSinkProxy_ == nullptr) {
85 DHLOGE("Daudio sink proxy not init.");
86 DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_INIT_FAIL, DISTRIBUTED_HARDWARE_AUDIO_SINK_SA_ID,
87 ERR_DH_AUDIO_SA_PROXY_NOT_INIT, "daudio sink proxy not init.");
88 return ERR_DH_AUDIO_SA_PROXY_NOT_INIT;
89 }
90
91 int32_t ret = dAudioSinkProxy_->ReleaseSink();
92 dAudioSinkProxy_ = nullptr;
93 return ret;
94 }
95
SubscribeLocalHardware(const std::string & dhId,const std::string & param)96 int32_t DAudioSinkHandler::SubscribeLocalHardware(const std::string &dhId, const std::string ¶m)
97 {
98 DHLOGI("Subscribe to local hardware.");
99 std::lock_guard<std::mutex> lock(sinkProxyMutex_);
100 CHECK_NULL_RETURN(dAudioSinkProxy_, ERR_DH_AUDIO_SA_PROXY_NOT_INIT);
101 if (dhId.length() > DAUDIO_MAX_DEVICE_ID_LEN) {
102 return ERR_DH_AUDIO_SA_DEVID_ILLEGAL;
103 }
104 std::string reduceDhId = dhId;
105 int32_t ret = dAudioSinkProxy_->SubscribeLocalHardware(reduceDhId, param);
106 return ret;
107 }
108
UnsubscribeLocalHardware(const std::string & dhId)109 int32_t DAudioSinkHandler::UnsubscribeLocalHardware(const std::string &dhId)
110 {
111 DHLOGI("Unsubscribe from local hardware.");
112 std::lock_guard<std::mutex> lock(sinkProxyMutex_);
113 CHECK_NULL_RETURN(dAudioSinkProxy_, ERR_DH_AUDIO_SA_PROXY_NOT_INIT);
114 if (dhId.length() > DAUDIO_MAX_DEVICE_ID_LEN) {
115 return ERR_DH_AUDIO_SA_DEVID_ILLEGAL;
116 }
117 std::string reduceDhId = dhId;
118 int32_t ret = dAudioSinkProxy_->UnsubscribeLocalHardware(reduceDhId);
119 return ret;
120 }
121
OnRemoteSinkSvrDied(const wptr<IRemoteObject> & remote)122 void DAudioSinkHandler::OnRemoteSinkSvrDied(const wptr<IRemoteObject> &remote)
123 {
124 DHLOGI("The daudio service of sink device died.");
125 sptr<IRemoteObject> remoteObject = remote.promote();
126 CHECK_NULL_VOID(remoteObject);
127
128 std::lock_guard<std::mutex> lock(sinkProxyMutex_);
129 if ((dAudioSinkProxy_ != nullptr) && (dAudioSinkProxy_->AsObject() != nullptr)) {
130 dAudioSinkProxy_->AsObject()->RemoveDeathRecipient(sinkSvrRecipient_);
131 dAudioSinkProxy_ = nullptr;
132 }
133 }
134
FinishStartSA(const std::string & param,const sptr<IRemoteObject> & remoteObject)135 void DAudioSinkHandler::FinishStartSA(const std::string ¶m, const sptr<IRemoteObject> &remoteObject)
136 {
137 DHLOGI("Finish start SA.");
138 std::lock_guard<std::mutex> lock(sinkProxyMutex_);
139 if (remoteObject != nullptr) {
140 remoteObject->AddDeathRecipient(sinkSvrRecipient_);
141 }
142 dAudioSinkProxy_ = iface_cast<IDAudioSink>(remoteObject);
143 if ((dAudioSinkProxy_ == nullptr) || (!dAudioSinkProxy_->AsObject())) {
144 DHLOGE("Failed to get daudio sink proxy.");
145 DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_INIT_FAIL, DISTRIBUTED_HARDWARE_AUDIO_SINK_SA_ID,
146 ERR_DH_AUDIO_SA_PROXY_NOT_INIT, "daudio sink get proxy failed.");
147 return;
148 }
149 dAudioSinkProxy_->InitSink(param, dAudioSinkIpcCallback_);
150 sinkProxyConVar_.notify_one();
151 DAudioHisysevent::GetInstance().SysEventWriteBehavior(DAUDIO_INIT, "daudio sink sa load success.");
152 }
153
OnRemoteDied(const wptr<IRemoteObject> & remote)154 void DAudioSinkHandler::DAudioSinkSvrRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
155 {
156 DAudioSinkHandler::GetInstance().OnRemoteSinkSvrDied(remote);
157 }
158
GetSinkHardwareHandler()159 IDistributedHardwareSink *GetSinkHardwareHandler()
160 {
161 DHLOGD("Get sink hardware handler.");
162 return &DAudioSinkHandler::GetInstance();
163 }
164
RegisterPrivacyResources(std::shared_ptr<PrivacyResourcesListener> listener)165 int32_t DAudioSinkHandler::RegisterPrivacyResources(std::shared_ptr<PrivacyResourcesListener> listener)
166 {
167 DHLOGI("RegisterPrivacyResources start.");
168 CHECK_NULL_RETURN(dAudioSinkIpcCallback_, ERR_DH_AUDIO_SA_PROXY_NOT_INIT);
169 dAudioSinkIpcCallback_->PushPrivacyResCallback(listener);
170 return DH_SUCCESS;
171 }
172
PauseDistributedHardware(const std::string & networkId)173 int32_t DAudioSinkHandler::PauseDistributedHardware(const std::string &networkId)
174 {
175 DHLOGI("pause distributed hardware.");
176 std::lock_guard<std::mutex> lock(sinkProxyMutex_);
177 CHECK_NULL_RETURN(dAudioSinkProxy_, ERR_DH_AUDIO_SA_PROXY_NOT_INIT);
178 return dAudioSinkProxy_->PauseDistributedHardware(networkId);
179 }
180
ResumeDistributedHardware(const std::string & networkId)181 int32_t DAudioSinkHandler::ResumeDistributedHardware(const std::string &networkId)
182 {
183 DHLOGI("resume distributed hardware.");
184 std::lock_guard<std::mutex> lock(sinkProxyMutex_);
185 CHECK_NULL_RETURN(dAudioSinkProxy_, ERR_DH_AUDIO_SA_PROXY_NOT_INIT);
186 return dAudioSinkProxy_->ResumeDistributedHardware(networkId);
187 }
188
StopDistributedHardware(const std::string & networkId)189 int32_t DAudioSinkHandler::StopDistributedHardware(const std::string &networkId)
190 {
191 DHLOGI("stop distributed hardware.");
192 std::lock_guard<std::mutex> lock(sinkProxyMutex_);
193 CHECK_NULL_RETURN(dAudioSinkProxy_, ERR_DH_AUDIO_SA_PROXY_NOT_INIT);
194 return dAudioSinkProxy_->StopDistributedHardware(networkId);
195 }
196 } // namespace DistributedHardware
197 } // namespace OHOS