1 /*
2 * Copyright (c) 2021-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 "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 "nlohmann/json.hpp"
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 REGISTER_SYSTEM_ABILITY_BY_ID(DistributedHardwareService, DISTRIBUTED_HARDWARE_SA_ID, true);
46
DistributedHardwareService(int32_t saId,bool runOnCreate)47 DistributedHardwareService::DistributedHardwareService(int32_t saId, bool runOnCreate)
48 : SystemAbility(saId, runOnCreate)
49 {
50 }
51
OnStart()52 void DistributedHardwareService::OnStart()
53 {
54 DHLOGI("DistributedHardwareService::OnStart start");
55 HiSysEventWriteMsg(DHFWK_INIT_BEGIN, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
56 "dhfwk sa start on demand.");
57
58 if (state_ == ServiceRunningState::STATE_RUNNING) {
59 DHLOGI("DistributedHardwareService has already started.");
60 return;
61 }
62 if (!Init()) {
63 DHLOGE("failed to init DistributedHardwareService");
64 return;
65 }
66 state_ = ServiceRunningState::STATE_RUNNING;
67 DHLOGI("DistributedHardwareService::OnStart start service success.");
68 }
69
Init()70 bool DistributedHardwareService::Init()
71 {
72 DHLOGI("DistributedHardwareService::Init ready to init.");
73 if (!registerToService_) {
74 bool ret = Publish(this);
75 if (!ret) {
76 DHLOGE("DistributedHardwareService::Init Publish failed!");
77 HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
78 "dhfwk sa init publish failed.");
79 return false;
80 }
81 registerToService_ = true;
82 }
83 auto ret = AccessManager::GetInstance()->Init();
84 if (ret != DH_FWK_SUCCESS) {
85 DHLOGE("DistributedHardwareService::Init failed.");
86 HiSysEventWriteErrCodeMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
87 ret, "dhfwk sa AccessManager init fail.");
88 return false;
89 }
90 DHLOGI("DistributedHardwareService::Init init success.");
91 HiSysEventWriteMsg(DHFWK_INIT_END, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
92 "dhfwk sa init success.");
93 return true;
94 }
95
OnStop()96 void DistributedHardwareService::OnStop()
97 {
98 DHLOGI("DistributedHardwareService::OnStop ready to stop service.");
99 state_ = ServiceRunningState::STATE_NOT_START;
100 registerToService_ = false;
101 }
102
RegisterPublisherListener(const DHTopic topic,const sptr<IPublisherListener> & listener)103 int32_t DistributedHardwareService::RegisterPublisherListener(const DHTopic topic,
104 const sptr<IPublisherListener> &listener)
105 {
106 Publisher::GetInstance().RegisterListener(topic, listener);
107 return DH_FWK_SUCCESS;
108 }
109
UnregisterPublisherListener(const DHTopic topic,const sptr<IPublisherListener> & listener)110 int32_t DistributedHardwareService::UnregisterPublisherListener(const DHTopic topic,
111 const sptr<IPublisherListener> &listener)
112 {
113 Publisher::GetInstance().UnregisterListener(topic, listener);
114 return DH_FWK_SUCCESS;
115 }
116
PublishMessage(const DHTopic topic,const std::string & msg)117 int32_t DistributedHardwareService::PublishMessage(const DHTopic topic, const std::string &msg)
118 {
119 Publisher::GetInstance().PublishMessage(topic, msg);
120 return DH_FWK_SUCCESS;
121 }
122
QueryLocalSysSpec(const QueryLocalSysSpecType spec)123 std::string DistributedHardwareService::QueryLocalSysSpec(const QueryLocalSysSpecType spec)
124 {
125 DeviceInfo localDevInfo = DHContext::GetInstance().GetDeviceInfo();
126 std::vector<std::shared_ptr<CapabilityInfo>> resInfos;
127 CapabilityInfoManager::GetInstance()->GetCapabilitiesByDeviceId(localDevInfo.deviceId, resInfos);
128 DHType targetDhType = DHType::UNKNOWN;
129 std::string targetKey = "";
130 switch (spec) {
131 case QueryLocalSysSpecType::HISTREAMER_AUDIO_ENCODER:
132 targetKey = KEY_HISTREAMER_AUDIO_ENCODER;
133 targetDhType = DHType::AUDIO;
134 break;
135 case QueryLocalSysSpecType::HISTREAMER_AUDIO_DECODER:
136 targetKey = KEY_HISTREAMER_AUDIO_DECODER;
137 targetDhType = DHType::AUDIO;
138 break;
139 case QueryLocalSysSpecType::HISTREAMER_VIDEO_ENCODER:
140 targetKey = KEY_HISTREAMER_VIDEO_ENCODER;
141 targetDhType = DHType::SCREEN;
142 break;
143 case QueryLocalSysSpecType::HISTREAMER_VIDEO_DECODER:
144 targetKey = KEY_HISTREAMER_VIDEO_DECODER;
145 targetDhType = DHType::SCREEN;
146 break;
147 default:
148 break;
149 }
150
151 DHLOGE("QueryLocalSysSpec targetKey: %s, targetDhType: %" PRIu32, targetKey.c_str(), (uint32_t)targetDhType);
152 if (targetDhType == DHType::UNKNOWN) {
153 DHLOGE("Can not find matched dhtype");
154 return "";
155 }
156
157 std::string attrs = "";
158 for (const auto &cap : resInfos) {
159 if (cap->GetDHType() != targetDhType) {
160 continue;
161 }
162 attrs = cap->GetDHAttrs();
163 break;
164 }
165 if (attrs.empty()) {
166 DHLOGE("Can not find dh attrs");
167 return "";
168 }
169
170 return QueryDhSysSpec(targetKey, attrs);
171 }
172
QueryDhSysSpec(const std::string & targetKey,std::string & attrs)173 std::string DistributedHardwareService::QueryDhSysSpec(const std::string &targetKey, std::string &attrs)
174 {
175 nlohmann::json attrJson = nlohmann::json::parse(attrs, nullptr, false);
176 if (attrJson.is_discarded()) {
177 DHLOGE("attrs json is invalid, attrs: %s", attrs.c_str());
178 return "";
179 }
180
181 if (!IsString(attrJson, targetKey)) {
182 DHLOGE("Attrs Json not contains key: %s", targetKey.c_str());
183 return "";
184 }
185 return attrJson.at(targetKey).get<std::string>();
186 }
187
InitializeAVCenter(const TransRole & transRole,int32_t & engineId)188 int32_t DistributedHardwareService::InitializeAVCenter(const TransRole &transRole, int32_t &engineId)
189 {
190 return AVTransControlCenter::GetInstance().InitializeAVCenter(transRole, engineId);
191 }
192
ReleaseAVCenter(int32_t engineId)193 int32_t DistributedHardwareService::ReleaseAVCenter(int32_t engineId)
194 {
195 return AVTransControlCenter::GetInstance().ReleaseAVCenter(engineId);
196 }
197
CreateControlChannel(int32_t engineId,const std::string & peerDevId)198 int32_t DistributedHardwareService::CreateControlChannel(int32_t engineId, const std::string &peerDevId)
199 {
200 return AVTransControlCenter::GetInstance().CreateControlChannel(engineId, peerDevId);
201 }
202
NotifyAVCenter(int32_t engineId,const AVTransEvent & event)203 int32_t DistributedHardwareService::NotifyAVCenter(int32_t engineId, const AVTransEvent &event)
204 {
205 return AVTransControlCenter::GetInstance().NotifyAVCenter(engineId, event);
206 }
207
RegisterCtlCenterCallback(int32_t engineId,const sptr<IAVTransControlCenterCallback> & callback)208 int32_t DistributedHardwareService::RegisterCtlCenterCallback(int32_t engineId,
209 const sptr<IAVTransControlCenterCallback> &callback)
210 {
211 return AVTransControlCenter::GetInstance().RegisterCtlCenterCallback(engineId, callback);
212 }
213
NotifySourceRemoteSinkStarted(std::string & deviceId)214 int32_t DistributedHardwareService::NotifySourceRemoteSinkStarted(std::string &deviceId)
215 {
216 DHLOGI("DistributedHardwareService NotifySourceRemoteSinkStarted Init DHMS Ready Start.");
217 Publisher::GetInstance().PublishMessage(DHTopic::TOPIC_INIT_DHMS_READY, deviceId);
218 DHLOGI("DistributedHardwareService NotifySourceRemoteSinkStarted Init DHMS Ready End.");
219 return DH_FWK_SUCCESS;
220 }
221
Dump(int32_t fd,const std::vector<std::u16string> & args)222 int DistributedHardwareService::Dump(int32_t fd, const std::vector<std::u16string>& args)
223 {
224 DHLOGI("DistributedHardwareService Dump.");
225
226 std::vector<std::string> argsStr {};
227 for (auto item : args) {
228 argsStr.emplace_back(Str16ToStr8(item));
229 }
230
231 std::string result("");
232 int ret = AccessManager::GetInstance()->Dump(argsStr, result);
233 if (ret != DH_FWK_SUCCESS) {
234 DHLOGE("Dump error, ret = %d", ret);
235 }
236
237 if (dprintf(fd, "%s\n", result.c_str()) < 0) {
238 DHLOGE("Hidump dprintf error");
239 ret = ERR_DH_FWK_HIDUMP_DPRINTF_ERROR;
240 }
241
242 return ret;
243 }
244
PauseDistributedHardware(DHType dhType,const std::string & networkId)245 int32_t DistributedHardwareService::PauseDistributedHardware(DHType dhType, const std::string &networkId)
246 {
247 std::map<DHType, IDistributedHardwareSink*> sinkMap = ComponentManager::GetInstance().GetDHSinkInstance();
248 if (sinkMap.find(dhType) == sinkMap.end()) {
249 DHLOGE("PauseDistributedHardware for DHType: %u not init sink handler", (uint32_t)dhType);
250 return ERR_DH_FWK_PARA_INVALID;
251 }
252 int32_t ret = sinkMap[dhType]->PauseDistributedHardware(networkId);
253 if (ret != 0) {
254 DHLOGE("PauseDistributedHardware for DHType: %u failed, ret: %d", (uint32_t)dhType, ret);
255 return ret;
256 }
257 return DH_FWK_SUCCESS;
258 }
259
ResumeDistributedHardware(DHType dhType,const std::string & networkId)260 int32_t DistributedHardwareService::ResumeDistributedHardware(DHType dhType, const std::string &networkId)
261 {
262 std::map<DHType, IDistributedHardwareSink*> sinkMap = ComponentManager::GetInstance().GetDHSinkInstance();
263 if (sinkMap.find(dhType) == sinkMap.end()) {
264 DHLOGE("ResumeDistributedHardware for DHType: %u not init sink handler", (uint32_t)dhType);
265 return ERR_DH_FWK_PARA_INVALID;
266 }
267 int32_t ret = sinkMap[dhType]->ResumeDistributedHardware(networkId);
268 if (ret != 0) {
269 DHLOGE("ResumeDistributedHardware for DHType: %u failed, ret: %d", (uint32_t)dhType, ret);
270 return ret;
271 }
272 return DH_FWK_SUCCESS;
273 }
274
StopDistributedHardware(DHType dhType,const std::string & networkId)275 int32_t DistributedHardwareService::StopDistributedHardware(DHType dhType, const std::string &networkId)
276 {
277 std::map<DHType, IDistributedHardwareSink*> sinkMap = ComponentManager::GetInstance().GetDHSinkInstance();
278 if (sinkMap.find(dhType) == sinkMap.end()) {
279 DHLOGE("StopDistributedHardware for DHType: %u not init sink handler", (uint32_t)dhType);
280 return ERR_DH_FWK_PARA_INVALID;
281 }
282 int32_t ret = sinkMap[dhType]->StopDistributedHardware(networkId);
283 if (ret != 0) {
284 DHLOGE("StopDistributedHardware for DHType: %u failed, ret: %d", (uint32_t)dhType, ret);
285 return ret;
286 }
287 return DH_FWK_SUCCESS;
288 }
289 } // namespace DistributedHardware
290 } // namespace OHOS
291