1 /*
2 * Copyright (c) 2021-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 "distributed_hardware_service.h"
17
18 #include <cinttypes>
19
20 #include "constants.h"
21 #include "if_system_ability_manager.h"
22 #include "ipc_skeleton.h"
23 #include "ipc_types.h"
24 #include "ipublisher_listener.h"
25 #include "iservice_registry.h"
26 #include "cJSON.h"
27 #include "string_ex.h"
28 #include "system_ability_definition.h"
29
30 #include "access_manager.h"
31 #include "av_trans_control_center.h"
32 #include "capability_info_manager.h"
33 #include "component_manager.h"
34 #include "dh_context.h"
35 #include "dh_utils_tool.h"
36 #include "dh_utils_hisysevent.h"
37 #include "distributed_hardware_fwk_kit_paras.h"
38 #include "distributed_hardware_errno.h"
39 #include "distributed_hardware_log.h"
40 #include "distributed_hardware_manager_factory.h"
41 #include "publisher.h"
42
43 namespace OHOS {
44 namespace DistributedHardware {
45 #undef DH_LOG_TAG
46 #define DH_LOG_TAG "DistributedHardwareService"
47 REGISTER_SYSTEM_ABILITY_BY_ID(DistributedHardwareService, DISTRIBUTED_HARDWARE_SA_ID, true);
48 namespace {
49 constexpr int32_t INIT_BUSINESS_DELAY_TIME_MS = 5 * 100;
50 const std::string INIT_TASK_ID = "CheckAndInitDH";
51 }
52
DistributedHardwareService(int32_t saId,bool runOnCreate)53 DistributedHardwareService::DistributedHardwareService(int32_t saId, bool runOnCreate)
54 : SystemAbility(saId, runOnCreate)
55 {
56 }
57
OnStart()58 void DistributedHardwareService::OnStart()
59 {
60 DHLOGI("DistributedHardwareService::OnStart start");
61 HiSysEventWriteMsg(DHFWK_INIT_BEGIN, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
62 "dhfwk sa start on demand.");
63
64 if (state_ == ServiceRunningState::STATE_RUNNING) {
65 DHLOGI("DistributedHardwareService has already started.");
66 return;
67 }
68 if (!Init()) {
69 DHLOGE("failed to init DistributedHardwareService");
70 return;
71 }
72 state_ = ServiceRunningState::STATE_RUNNING;
73 DHLOGI("DistributedHardwareService::OnStart start service success.");
74 }
75
Init()76 bool DistributedHardwareService::Init()
77 {
78 DHLOGI("DistributedHardwareService::Init ready to init.");
79 if (!registerToService_) {
80 bool ret = Publish(this);
81 if (!ret) {
82 DHLOGE("DistributedHardwareService::Init Publish failed!");
83 HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
84 "dhfwk sa init publish failed.");
85 return false;
86 }
87 registerToService_ = true;
88 }
89 std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create(true);
90 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
91 auto executeInnerFunc = [this] { DoBusinessInit(); };
92 eventHandler_->PostTask(executeInnerFunc, INIT_TASK_ID, 0);
93 DHLOGI("DistributedHardwareService::Init success.");
94 HiSysEventWriteMsg(DHFWK_INIT_END, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
95 "dhfwk sa init success.");
96 return true;
97 }
98
InitLocalDevInfo()99 void DistributedHardwareService::InitLocalDevInfo()
100 {
101 DHLOGI("Init Local device info in DB");
102 DistributedHardwareManagerFactory::GetInstance().InitLocalDevInfo();
103 }
104
DoBusinessInit()105 bool DistributedHardwareService::DoBusinessInit()
106 {
107 if (!IsDepSAStart()) {
108 DHLOGW("Depend sa not start");
109 auto executeInnerFunc = [this] { DoBusinessInit(); };
110 eventHandler_->PostTask(executeInnerFunc, INIT_TASK_ID, INIT_BUSINESS_DELAY_TIME_MS);
111 return false;
112 }
113
114 DHLOGI("Init AccessManager");
115 auto ret = AccessManager::GetInstance()->Init();
116 if (ret != DH_FWK_SUCCESS) {
117 DHLOGE("DistributedHardwareService::Init failed.");
118 HiSysEventWriteErrCodeMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
119 ret, "dhfwk sa AccessManager init fail.");
120 }
121 InitLocalDevInfo();
122 AccessManager::GetInstance()->CheckTrustedDeviceOnline();
123 return true;
124 }
125
IsDepSAStart()126 bool DistributedHardwareService::IsDepSAStart()
127 {
128 sptr<ISystemAbilityManager> saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
129 if (saMgr == nullptr) {
130 DHLOGE("Get System Ability Manager failed");
131 return false;
132 }
133 DHLOGI("Check DSoftbus sa");
134 sptr<IRemoteObject> remoteObject = saMgr->CheckSystemAbility(SOFTBUS_SERVER_SA_ID);
135 if (remoteObject == nullptr) {
136 DHLOGW("DSoftbus not start");
137 return false;
138 }
139 DHLOGI("Check KVDB sa");
140 remoteObject = saMgr->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
141 if (remoteObject == nullptr) {
142 DHLOGW("KVDB not start");
143 return false;
144 }
145 DHLOGI("Check DM sa");
146 remoteObject = saMgr->CheckSystemAbility(DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID);
147 if (remoteObject == nullptr) {
148 DHLOGW("DM not start");
149 return false;
150 }
151 return true;
152 }
153
OnStop()154 void DistributedHardwareService::OnStop()
155 {
156 DHLOGI("DistributedHardwareService::OnStop ready to stop service.");
157 state_ = ServiceRunningState::STATE_NOT_START;
158 registerToService_ = false;
159 }
160
RegisterPublisherListener(const DHTopic topic,const sptr<IPublisherListener> listener)161 int32_t DistributedHardwareService::RegisterPublisherListener(const DHTopic topic,
162 const sptr<IPublisherListener> listener)
163 {
164 Publisher::GetInstance().RegisterListener(topic, listener);
165 return DH_FWK_SUCCESS;
166 }
167
UnregisterPublisherListener(const DHTopic topic,const sptr<IPublisherListener> listener)168 int32_t DistributedHardwareService::UnregisterPublisherListener(const DHTopic topic,
169 const sptr<IPublisherListener> listener)
170 {
171 Publisher::GetInstance().UnregisterListener(topic, listener);
172 return DH_FWK_SUCCESS;
173 }
174
PublishMessage(const DHTopic topic,const std::string & msg)175 int32_t DistributedHardwareService::PublishMessage(const DHTopic topic, const std::string &msg)
176 {
177 DHContext::GetInstance();
178 Publisher::GetInstance().PublishMessage(topic, msg);
179 return DH_FWK_SUCCESS;
180 }
181
QueryLocalSysSpec(const QueryLocalSysSpecType spec)182 std::string DistributedHardwareService::QueryLocalSysSpec(const QueryLocalSysSpecType spec)
183 {
184 DeviceInfo localDevInfo = DHContext::GetInstance().GetDeviceInfo();
185 std::vector<std::shared_ptr<CapabilityInfo>> resInfos;
186 CapabilityInfoManager::GetInstance()->GetCapabilitiesByDeviceId(localDevInfo.deviceId, resInfos);
187 DHType targetDhType = DHType::UNKNOWN;
188 std::string targetKey = "";
189 switch (spec) {
190 case QueryLocalSysSpecType::HISTREAMER_AUDIO_ENCODER:
191 targetKey = KEY_HISTREAMER_AUDIO_ENCODER;
192 targetDhType = DHType::AUDIO;
193 break;
194 case QueryLocalSysSpecType::HISTREAMER_AUDIO_DECODER:
195 targetKey = KEY_HISTREAMER_AUDIO_DECODER;
196 targetDhType = DHType::AUDIO;
197 break;
198 case QueryLocalSysSpecType::HISTREAMER_VIDEO_ENCODER:
199 targetKey = KEY_HISTREAMER_VIDEO_ENCODER;
200 targetDhType = DHType::SCREEN;
201 break;
202 case QueryLocalSysSpecType::HISTREAMER_VIDEO_DECODER:
203 targetKey = KEY_HISTREAMER_VIDEO_DECODER;
204 targetDhType = DHType::SCREEN;
205 break;
206 default:
207 break;
208 }
209
210 DHLOGE("QueryLocalSysSpec targetKey: %{public}s, targetDhType: %{public}" PRIu32, targetKey.c_str(),
211 (uint32_t)targetDhType);
212 if (targetDhType == DHType::UNKNOWN) {
213 DHLOGE("Can not find matched dhtype");
214 return "";
215 }
216
217 std::string attrs = "";
218 for (const auto &cap : resInfos) {
219 if (cap->GetDHType() != targetDhType) {
220 continue;
221 }
222 attrs = cap->GetDHAttrs();
223 break;
224 }
225 if (attrs.empty()) {
226 DHLOGE("Can not find dh attrs");
227 return "";
228 }
229
230 return QueryDhSysSpec(targetKey, attrs);
231 }
232
QueryDhSysSpec(const std::string & targetKey,std::string & attrs)233 std::string DistributedHardwareService::QueryDhSysSpec(const std::string &targetKey, std::string &attrs)
234 {
235 cJSON *attrJson = cJSON_Parse(attrs.c_str());
236 if (attrJson == NULL) {
237 DHLOGE("attrs json is invalid, attrs: %{public}s", attrs.c_str());
238 return "";
239 }
240 if (!IsString(attrJson, targetKey)) {
241 DHLOGE("Attrs Json not contains key: %{public}s", targetKey.c_str());
242 cJSON_Delete(attrJson);
243 return "";
244 }
245 std::string result = cJSON_GetObjectItem(attrJson, targetKey.c_str())->valuestring;
246 cJSON_Delete(attrJson);
247 return result;
248 }
249
InitializeAVCenter(const TransRole & transRole,int32_t & engineId)250 int32_t DistributedHardwareService::InitializeAVCenter(const TransRole &transRole, int32_t &engineId)
251 {
252 return AVTransControlCenter::GetInstance().InitializeAVCenter(transRole, engineId);
253 }
254
ReleaseAVCenter(int32_t engineId)255 int32_t DistributedHardwareService::ReleaseAVCenter(int32_t engineId)
256 {
257 return AVTransControlCenter::GetInstance().ReleaseAVCenter(engineId);
258 }
259
CreateControlChannel(int32_t engineId,const std::string & peerDevId)260 int32_t DistributedHardwareService::CreateControlChannel(int32_t engineId, const std::string &peerDevId)
261 {
262 return AVTransControlCenter::GetInstance().CreateControlChannel(engineId, peerDevId);
263 }
264
NotifyAVCenter(int32_t engineId,const AVTransEvent & event)265 int32_t DistributedHardwareService::NotifyAVCenter(int32_t engineId, const AVTransEvent &event)
266 {
267 return AVTransControlCenter::GetInstance().NotifyAVCenter(engineId, event);
268 }
269
RegisterCtlCenterCallback(int32_t engineId,const sptr<IAVTransControlCenterCallback> callback)270 int32_t DistributedHardwareService::RegisterCtlCenterCallback(int32_t engineId,
271 const sptr<IAVTransControlCenterCallback> callback)
272 {
273 return AVTransControlCenter::GetInstance().RegisterCtlCenterCallback(engineId, callback);
274 }
275
NotifySourceRemoteSinkStarted(std::string & deviceId)276 int32_t DistributedHardwareService::NotifySourceRemoteSinkStarted(std::string &deviceId)
277 {
278 DHLOGI("DistributedHardwareService NotifySourceRemoteSinkStarted Init DHMS Ready Start.");
279 Publisher::GetInstance().PublishMessage(DHTopic::TOPIC_INIT_DHMS_READY, deviceId);
280 DHLOGI("DistributedHardwareService NotifySourceRemoteSinkStarted Init DHMS Ready End.");
281 return DH_FWK_SUCCESS;
282 }
283
Dump(int32_t fd,const std::vector<std::u16string> & args)284 int DistributedHardwareService::Dump(int32_t fd, const std::vector<std::u16string>& args)
285 {
286 DHLOGI("DistributedHardwareService Dump.");
287
288 std::vector<std::string> argsStr {};
289 for (auto item : args) {
290 argsStr.emplace_back(Str16ToStr8(item));
291 }
292
293 std::string result("");
294 int ret = AccessManager::GetInstance()->Dump(argsStr, result);
295 if (ret != DH_FWK_SUCCESS) {
296 DHLOGE("Dump error, ret = %{public}d", ret);
297 }
298
299 if (dprintf(fd, "%s\n", result.c_str()) < 0) {
300 DHLOGE("Hidump dprintf error");
301 ret = ERR_DH_FWK_HIDUMP_DPRINTF_ERROR;
302 }
303
304 return ret;
305 }
306
PauseDistributedHardware(DHType dhType,const std::string & networkId)307 int32_t DistributedHardwareService::PauseDistributedHardware(DHType dhType, const std::string &networkId)
308 {
309 if (!IsIdLengthValid(networkId)) {
310 return ERR_DH_FWK_PARA_INVALID;
311 }
312 std::map<DHType, IDistributedHardwareSink*> sinkMap = ComponentManager::GetInstance().GetDHSinkInstance();
313 if (sinkMap.find(dhType) == sinkMap.end()) {
314 DHLOGE("PauseDistributedHardware for DHType: %{public}u not init sink handler", (uint32_t)dhType);
315 return ERR_DH_FWK_PARA_INVALID;
316 }
317 int32_t ret = sinkMap[dhType]->PauseDistributedHardware(networkId);
318 if (ret != 0) {
319 DHLOGE("PauseDistributedHardware for DHType: %{public}u failed, ret: %{public}d", (uint32_t)dhType, ret);
320 return ret;
321 }
322 return DH_FWK_SUCCESS;
323 }
324
ResumeDistributedHardware(DHType dhType,const std::string & networkId)325 int32_t DistributedHardwareService::ResumeDistributedHardware(DHType dhType, const std::string &networkId)
326 {
327 if (!IsIdLengthValid(networkId)) {
328 return ERR_DH_FWK_PARA_INVALID;
329 }
330 std::map<DHType, IDistributedHardwareSink*> sinkMap = ComponentManager::GetInstance().GetDHSinkInstance();
331 if (sinkMap.find(dhType) == sinkMap.end()) {
332 DHLOGE("ResumeDistributedHardware for DHType: %{public}u not init sink handler", (uint32_t)dhType);
333 return ERR_DH_FWK_PARA_INVALID;
334 }
335 int32_t ret = sinkMap[dhType]->ResumeDistributedHardware(networkId);
336 if (ret != 0) {
337 DHLOGE("ResumeDistributedHardware for DHType: %{public}u failed, ret: %{public}d", (uint32_t)dhType, ret);
338 return ret;
339 }
340 return DH_FWK_SUCCESS;
341 }
342
StopDistributedHardware(DHType dhType,const std::string & networkId)343 int32_t DistributedHardwareService::StopDistributedHardware(DHType dhType, const std::string &networkId)
344 {
345 if (!IsIdLengthValid(networkId)) {
346 return ERR_DH_FWK_PARA_INVALID;
347 }
348 std::map<DHType, IDistributedHardwareSink*> sinkMap = ComponentManager::GetInstance().GetDHSinkInstance();
349 if (sinkMap.find(dhType) == sinkMap.end()) {
350 DHLOGE("StopDistributedHardware for DHType: %{public}u not init sink handler", (uint32_t)dhType);
351 return ERR_DH_FWK_PARA_INVALID;
352 }
353 int32_t ret = sinkMap[dhType]->StopDistributedHardware(networkId);
354 if (ret != 0) {
355 DHLOGE("StopDistributedHardware for DHType: %{public}u failed, ret: %{public}d", (uint32_t)dhType, ret);
356 return ret;
357 }
358 return DH_FWK_SUCCESS;
359 }
360 } // namespace DistributedHardware
361 } // namespace OHOS
362