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 &params)
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 &param)
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 &param, 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