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 "offline_task.h"
17
18 #include <pthread.h>
19 #include <thread>
20
21 #include "ffrt.h"
22
23 #include "anonymous_string.h"
24 #include "capability_info_manager.h"
25 #include "constants.h"
26 #include "dh_context.h"
27 #include "dh_utils_tool.h"
28 #include "distributed_hardware_errno.h"
29 #include "distributed_hardware_log.h"
30 #include "distributed_hardware_manager_factory.h"
31 #include "meta_info_manager.h"
32 #include "task_board.h"
33 #include "task_executor.h"
34 #include "task_factory.h"
35
36 namespace OHOS {
37 namespace DistributedHardware {
38 #undef DH_LOG_TAG
39 #define DH_LOG_TAG "OffLineTask"
40
OffLineTask(const std::string &networkId, const std::string &uuid, const std::string &udid, const std::string &dhId, const DHType dhType)41 OffLineTask::OffLineTask(const std::string &networkId, const std::string &uuid, const std::string &udid,
42 const std::string &dhId, const DHType dhType) : Task(networkId, uuid, udid, dhId, dhType)
43 {
44 this->SetTaskType(TaskType::OFF_LINE);
45 this->SetTaskSteps({TaskStep::META_DISABLE_TASK, TaskStep::UNREGISTER_OFFLINE_DISTRIBUTED_HARDWARE,
46 TaskStep::WAIT_UNREGISTGER_COMPLETE, TaskStep::CLEAR_OFFLINE_INFO});
47 DHLOGD("OffLineTask id: %{public}s, networkId: %{public}s, uuid: %{public}s, udid: %{public}s",
48 GetId().c_str(), GetAnonyString(GetNetworkId()).c_str(), GetAnonyString(GetUUID()).c_str(),
49 GetAnonyString(GetUDID()).c_str());
50 }
51
~OffLineTask()52 OffLineTask::~OffLineTask()
53 {
54 DHLOGD("id = %{public}s, uuid = %{public}s", GetId().c_str(), GetAnonyString(GetUUID()).c_str());
55 }
56
DoTask()57 void OffLineTask::DoTask()
58 {
59 ffrt::submit([this]() { this->DoTaskInner(); });
60 }
61
DoTaskInner()62 void OffLineTask::DoTaskInner()
63 {
64 int32_t ret = pthread_setname_np(pthread_self(), OFFLINE_TASK_INNER);
65 if (ret != DH_FWK_SUCCESS) {
66 DHLOGE("DoTaskInner setname failed.");
67 }
68 DHLOGD("start offline task, id = %{public}s, uuid = %{public}s", GetId().c_str(),
69 GetAnonyString(GetUUID()).c_str());
70 this->SetTaskState(TaskState::RUNNING);
71 for (const auto& step : this->GetTaskSteps()) {
72 switch (step) {
73 case TaskStep::UNREGISTER_OFFLINE_DISTRIBUTED_HARDWARE: {
74 CreateDisableTask();
75 break;
76 }
77 case TaskStep::WAIT_UNREGISTGER_COMPLETE: {
78 WaitDisableTaskFinish();
79 break;
80 }
81 case TaskStep::CLEAR_OFFLINE_INFO: {
82 ClearOffLineInfo();
83 break;
84 }
85 case TaskStep::META_DISABLE_TASK: {
86 CreateMetaDisableTask();
87 break;
88 }
89 default: {
90 break;
91 }
92 }
93 }
94
95 this->SetTaskState(TaskState::SUCCESS);
96 DHLOGD("Finish OffLine task, remove it, id: %{public}s", GetId().c_str());
97 TaskBoard::GetInstance().RemoveTask(this->GetId());
98 if (DHContext::GetInstance().GetRealTimeOnlineDeviceCount() == 0 &&
99 DHContext::GetInstance().GetIsomerismConnectCount() == 0 &&
100 TaskBoard::GetInstance().IsAllTaskFinish()) {
101 DHLOGI("all devices are offline, start to free the resource");
102 DistributedHardwareManagerFactory::GetInstance().UnInit();
103 }
104 }
105
CreateDisableTask()106 void OffLineTask::CreateDisableTask()
107 {
108 DHLOGI("networkId = %{public}s, uuid = %{public}s", GetAnonyString(GetNetworkId()).c_str(),
109 GetAnonyString(GetUUID()).c_str());
110 std::string deviceId = GetDeviceIdByUUID(GetUUID());
111 std::vector<std::pair<std::string, DHType>> devDhInfos;
112 std::vector<std::shared_ptr<CapabilityInfo>> capabilityInfos;
113 CapabilityInfoManager::GetInstance()->GetCapabilitiesByDeviceId(deviceId, capabilityInfos);
114 std::for_each(capabilityInfos.begin(), capabilityInfos.end(), [&](std::shared_ptr<CapabilityInfo> cap) {
115 devDhInfos.push_back({cap->GetDHId(), cap->GetDHType()});
116 });
117
118 if (devDhInfos.empty()) {
119 DHLOGW("Can not get cap info from CapabilityInfo, try use meta info");
120 std::vector<std::shared_ptr<MetaCapabilityInfo>> metaCapInfos;
121 std::string udidHash = DHContext::GetInstance().GetUdidHashIdByUUID(GetUUID());
122 MetaInfoManager::GetInstance()->GetMetaCapInfosByUdidHash(udidHash, metaCapInfos);
123 std::for_each(metaCapInfos.begin(), metaCapInfos.end(), [&](std::shared_ptr<MetaCapabilityInfo> cap) {
124 devDhInfos.push_back({cap->GetDHId(), cap->GetDHType()});
125 });
126 }
127
128 if (devDhInfos.empty()) {
129 DHLOGE("Can not get cap info, uuid = %{public}s, deviceId = %{public}s", GetAnonyString(GetUUID()).c_str(),
130 GetAnonyString(deviceId).c_str());
131 }
132
133 for (const auto &info : devDhInfos) {
134 TaskParam taskParam = {
135 .networkId = GetNetworkId(),
136 .uuid = GetUUID(),
137 .dhId = info.first,
138 .dhType = info.second
139 };
140 auto task = TaskFactory::GetInstance().CreateTask(TaskType::DISABLE, taskParam, shared_from_this());
141 TaskExecutor::GetInstance().PushTask(task);
142 }
143 }
144
WaitDisableTaskFinish()145 void OffLineTask::WaitDisableTaskFinish()
146 {
147 DHLOGI("start wait disable task finish");
148 std::unique_lock<std::mutex> waitLock(unFinishTaskMtx_);
149 finishCondVar_.wait(waitLock, [&] { return this->unFinishChildrenTasks_.empty(); });
150 DHLOGI("all disable task finish");
151 DHContext::GetInstance().RemoveOnlineDeviceIdEntryByNetworkId(GetNetworkId());
152 }
153
ClearOffLineInfo()154 void OffLineTask::ClearOffLineInfo()
155 {
156 DHLOGI("start clear resource when device offline, uuid = %{public}s", GetAnonyString(GetUUID()).c_str());
157 auto ret = CapabilityInfoManager::GetInstance()->RemoveCapabilityInfoInMem(GetDeviceIdByUUID(GetUUID()));
158 if (ret != DH_FWK_SUCCESS) {
159 DHLOGE("RemoveCapabilityInfoInMem failed, uuid = %{public}s, errCode = %{public}d",
160 GetAnonyString(GetUUID()).c_str(), ret);
161 }
162 }
163
NotifyFatherFinish(std::string taskId)164 void OffLineTask::NotifyFatherFinish(std::string taskId)
165 {
166 {
167 std::lock_guard<std::mutex> lock(unFinishTaskMtx_);
168 this->unFinishChildrenTasks_.erase(taskId);
169 }
170 finishCondVar_.notify_all();
171 }
172
AddChildrenTask(std::shared_ptr<Task> childrenTask)173 void OffLineTask::AddChildrenTask(std::shared_ptr<Task> childrenTask)
174 {
175 std::lock_guard<std::mutex> lock(unFinishTaskMtx_);
176 this->unFinishChildrenTasks_.insert(childrenTask->GetId());
177 }
178
CreateMetaDisableTask()179 void OffLineTask::CreateMetaDisableTask()
180 {
181 DHLOGI("CreateMetaDisableTask, networkId = %{public}s, uuid = %{public}s", GetAnonyString(GetNetworkId()).c_str(),
182 GetAnonyString(GetUUID()).c_str());
183 TaskParam taskParam = {
184 .networkId = GetNetworkId(),
185 .uuid = GetUUID(),
186 .dhId = GetDhId(),
187 .dhType = GetDhType()
188 };
189 auto task = TaskFactory::GetInstance().CreateTask(TaskType::META_DISABLE, taskParam, shared_from_this());
190 TaskExecutor::GetInstance().PushTask(task);
191 }
192 } // namespace DistributedHardware
193 } // namespace OHOS
194