1 /*
2 * Copyright (c) 2022 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
28 #undef DH_LOG_TAG
29 #define DH_LOG_TAG "DAudioSinkHandler"
30
31 namespace OHOS {
32 namespace DistributedHardware {
33 IMPLEMENT_SINGLE_INSTANCE(DAudioSinkHandler);
34
DAudioSinkHandler()35 DAudioSinkHandler::DAudioSinkHandler()
36 {
37 DHLOGD("DAudio sink handler constructed.");
38 }
39
~DAudioSinkHandler()40 DAudioSinkHandler::~DAudioSinkHandler()
41 {
42 DHLOGD("DAudio sink handler destructed.");
43 }
44
InitSink(const std::string & params)45 int32_t DAudioSinkHandler::InitSink(const std::string ¶ms)
46 {
47 DHLOGI("Init sink handler.");
48 DAUDIO_SYNC_TRACE(DAUDIO_SOURCE_LOAD_SYSTEM_ABILITY);
49 if (dAudioSinkProxy_ == nullptr) {
50 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
51 if (samgr == nullptr) {
52 DHLOGE("Failed to get system ability mgr.");
53 return ERR_DH_AUDIO_NULLPTR;
54 }
55 sptr<DAudioSinkLoadCallback> loadCallback(new DAudioSinkLoadCallback(params));
56 int32_t ret = samgr->LoadSystemAbility(DISTRIBUTED_HARDWARE_AUDIO_SINK_SA_ID, loadCallback);
57 if (ret != ERR_OK) {
58 DHLOGE("Failed to Load systemAbility ret code: %d.", ret);
59 DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_INIT_FAIL, DISTRIBUTED_HARDWARE_AUDIO_SINK_SA_ID,
60 ERR_DH_AUDIO_SA_LOAD_FAILED, "daudio sink LoadSystemAbility call failed.");
61 return ERR_DH_AUDIO_SA_LOAD_FAILED;
62 }
63 }
64
65 std::unique_lock<std::mutex> lock(sinkProxyMutex_);
66 auto waitStatus = sinkProxyConVar_.wait_for(lock, std::chrono::milliseconds(AUDIO_LOADSA_TIMEOUT_MS),
67 [this]() { return dAudioSinkProxy_ != nullptr; });
68 if (!waitStatus) {
69 DHLOGE("Audio load sa timeout.");
70 DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_INIT_FAIL, DISTRIBUTED_HARDWARE_AUDIO_SINK_SA_ID,
71 ERR_DH_AUDIO_SA_LOAD_TIMEOUT, "daudio sink sa load timeout.");
72 return ERR_DH_AUDIO_SA_LOAD_TIMEOUT;
73 }
74 return DH_SUCCESS;
75 }
76
ReleaseSink()77 int32_t DAudioSinkHandler::ReleaseSink()
78 {
79 DHLOGI("Release sink handler.");
80 std::lock_guard<std::mutex> lock(sinkProxyMutex_);
81 if (dAudioSinkProxy_ == nullptr) {
82 DHLOGE("Daudio sink proxy not init.");
83 DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_INIT_FAIL, DISTRIBUTED_HARDWARE_AUDIO_SINK_SA_ID,
84 ERR_DH_AUDIO_SA_PROXY_NOT_INIT, "daudio sink proxy not init.");
85 return ERR_DH_AUDIO_SA_PROXY_NOT_INIT;
86 }
87
88 int32_t ret = dAudioSinkProxy_->ReleaseSink();
89 dAudioSinkProxy_ = nullptr;
90 return ret;
91 }
92
SubscribeLocalHardware(const std::string & dhId,const std::string & param)93 int32_t DAudioSinkHandler::SubscribeLocalHardware(const std::string &dhId, const std::string ¶m)
94 {
95 DHLOGI("Subscribe to local hardware.");
96 std::lock_guard<std::mutex> lock(sinkProxyMutex_);
97 if (dAudioSinkProxy_ == nullptr) {
98 DHLOGE("daudio sink proxy not init.");
99 return ERR_DH_AUDIO_SA_PROXY_NOT_INIT;
100 }
101 if (dhId.length() > DAUDIO_MAX_DEVICE_ID_LEN) {
102 return ERR_DH_AUDIO_SA_DEVID_ILLEGAL;
103 }
104 int32_t ret = dAudioSinkProxy_->SubscribeLocalHardware(dhId, param);
105 return ret;
106 }
107
UnsubscribeLocalHardware(const std::string & dhId)108 int32_t DAudioSinkHandler::UnsubscribeLocalHardware(const std::string &dhId)
109 {
110 DHLOGI("Unsubscribe from local hardware.");
111 std::lock_guard<std::mutex> lock(sinkProxyMutex_);
112 if (dAudioSinkProxy_ == nullptr) {
113 DHLOGE("daudio sink proxy not init.");
114 return ERR_DH_AUDIO_SA_PROXY_NOT_INIT;
115 }
116 if (dhId.length() > DAUDIO_MAX_DEVICE_ID_LEN) {
117 return ERR_DH_AUDIO_SA_DEVID_ILLEGAL;
118 }
119 int32_t ret = dAudioSinkProxy_->UnsubscribeLocalHardware(dhId);
120 return ret;
121 }
122
OnRemoteSinkSvrDied(const wptr<IRemoteObject> & remote)123 void DAudioSinkHandler::OnRemoteSinkSvrDied(const wptr<IRemoteObject> &remote)
124 {
125 DHLOGD("The daudio service of sink device died.");
126 sptr<IRemoteObject> remoteObject = remote.promote();
127 if (remoteObject == nullptr) {
128 DHLOGE("OnRemoteDied remote promoted failed.");
129 return;
130 }
131
132 std::lock_guard<std::mutex> lock(sinkProxyMutex_);
133 if (dAudioSinkProxy_ != nullptr) {
134 dAudioSinkProxy_->AsObject()->RemoveDeathRecipient(sinkSvrRecipient_);
135 dAudioSinkProxy_ = nullptr;
136 }
137 }
138
FinishStartSA(const std::string & param,const sptr<IRemoteObject> & remoteObject)139 void DAudioSinkHandler::FinishStartSA(const std::string ¶m, const sptr<IRemoteObject> &remoteObject)
140 {
141 DHLOGD("Finish start SA.");
142 std::lock_guard<std::mutex> lock(sinkProxyMutex_);
143 remoteObject->AddDeathRecipient(sinkSvrRecipient_);
144 dAudioSinkProxy_ = iface_cast<IDAudioSink>(remoteObject);
145 if ((dAudioSinkProxy_ == nullptr) || (!dAudioSinkProxy_->AsObject())) {
146 DHLOGE("Failed to get daudio sink proxy.");
147 DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_INIT_FAIL, DISTRIBUTED_HARDWARE_AUDIO_SINK_SA_ID,
148 ERR_DH_AUDIO_SA_PROXY_NOT_INIT, "daudio sink get proxy failed.");
149 return;
150 }
151 dAudioSinkProxy_->InitSink(param);
152 sinkProxyConVar_.notify_one();
153 DAudioHisysevent::GetInstance().SysEventWriteBehavior(DAUDIO_INIT, "daudio sink sa load success.");
154 }
155
OnRemoteDied(const wptr<IRemoteObject> & remote)156 void DAudioSinkHandler::DAudioSinkSvrRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
157 {
158 DAudioSinkHandler::GetInstance().OnRemoteSinkSvrDied(remote);
159 }
160
GetSinkHardwareHandler()161 IDistributedHardwareSink *GetSinkHardwareHandler()
162 {
163 DHLOGD("Get sink hardware handler.");
164 return &DAudioSinkHandler::GetInstance();
165 }
166 } // namespace DistributedHardware
167 } // namespace OHOS