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