• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 "dh_context.h"
26 #include "dh_utils_tool.h"
27 #include "distributed_hardware_errno.h"
28 #include "distributed_hardware_log.h"
29 #include "distributed_hardware_manager_factory.h"
30 #include "meta_info_manager.h"
31 #include "task_board.h"
32 #include "task_executor.h"
33 #include "task_factory.h"
34 
35 namespace OHOS {
36 namespace DistributedHardware {
37 namespace {
38     constexpr uint16_t PHONE_TYPE = 14;
39     constexpr const char *OFFLINE_TASK_INNER = "OffLineTask";
40 }
41 #undef DH_LOG_TAG
42 #define DH_LOG_TAG "OffLineTask"
43 
OffLineTask(const std::string & networkId,const std::string & uuid,const std::string & udid,const std::string & dhId,const DHType dhType)44 OffLineTask::OffLineTask(const std::string &networkId, const std::string &uuid, const std::string &udid,
45     const std::string &dhId, const DHType dhType) : Task(networkId, uuid, udid, dhId, dhType)
46 {
47     this->SetTaskType(TaskType::OFF_LINE);
48     this->SetTaskSteps({TaskStep::META_DISABLE_TASK, TaskStep::UNREGISTER_OFFLINE_DISTRIBUTED_HARDWARE,
49         TaskStep::DISABLE_SINK, TaskStep::WAIT_UNREGISTGER_COMPLETE, TaskStep::CLEAR_OFFLINE_INFO});
50     DHLOGD("OffLineTask id: %{public}s, networkId: %{public}s, uuid: %{public}s, udid: %{public}s",
51         GetId().c_str(), GetAnonyString(GetNetworkId()).c_str(), GetAnonyString(GetUUID()).c_str(),
52         GetAnonyString(GetUDID()).c_str());
53 }
54 
~OffLineTask()55 OffLineTask::~OffLineTask()
56 {
57     DHLOGD("id = %{public}s, uuid = %{public}s", GetId().c_str(), GetAnonyString(GetUUID()).c_str());
58 }
59 
DoTask()60 void OffLineTask::DoTask()
61 {
62     ffrt::submit([this]() { this->DoTaskInner(); });
63 }
64 
DoTaskInner()65 void OffLineTask::DoTaskInner()
66 {
67     int32_t ret = pthread_setname_np(pthread_self(), OFFLINE_TASK_INNER);
68     if (ret != DH_FWK_SUCCESS) {
69         DHLOGE("DoTaskInner setname failed.");
70     }
71     DHLOGD("start offline task, id = %{public}s, uuid = %{public}s", GetId().c_str(),
72         GetAnonyString(GetUUID()).c_str());
73     this->SetTaskState(TaskState::RUNNING);
74     for (const auto& step : this->GetTaskSteps()) {
75         switch (step) {
76             case TaskStep::UNREGISTER_OFFLINE_DISTRIBUTED_HARDWARE: {
77                 CreateDisableTask();
78                 break;
79             }
80             case TaskStep::DISABLE_SINK: {
81                 CreateDisableSinkTask();
82                 break;
83             }
84             case TaskStep::WAIT_UNREGISTGER_COMPLETE: {
85                 WaitDisableTaskFinish();
86                 break;
87             }
88             case TaskStep::CLEAR_OFFLINE_INFO: {
89                 ClearOffLineInfo();
90                 break;
91             }
92             case TaskStep::META_DISABLE_TASK: {
93                 CreateMetaDisableTask();
94                 break;
95             }
96             default: {
97                 break;
98             }
99         }
100     }
101 
102     this->SetTaskState(TaskState::SUCCESS);
103     DHLOGI("Finish OffLine task, remove it, id: %{public}s", GetId().c_str());
104     TaskBoard::GetInstance().RemoveTask(this->GetId());
105     if (DHContext::GetInstance().GetRealTimeOnlineDeviceCount() == 0 &&
106         DHContext::GetInstance().GetIsomerismConnectCount() == 0 &&
107         TaskBoard::GetInstance().IsAllDisableTaskFinish()) {
108         DHLOGI("all devices are offline and all disable tasks are finished, start to free the resource");
109         DistributedHardwareManagerFactory::GetInstance().UnInit();
110     }
111 }
112 
CreateDisableTask()113 void OffLineTask::CreateDisableTask()
114 {
115     DHLOGI("networkId = %{public}s, uuid = %{public}s", GetAnonyString(GetNetworkId()).c_str(),
116         GetAnonyString(GetUUID()).c_str());
117     std::string deviceId = GetDeviceIdByUUID(GetUUID());
118     std::vector<std::pair<std::string, DHType>> devDhInfos;
119     std::vector<std::shared_ptr<CapabilityInfo>> capabilityInfos;
120     CapabilityInfoManager::GetInstance()->GetCapabilitiesByDeviceId(deviceId, capabilityInfos);
121     std::for_each(capabilityInfos.begin(), capabilityInfos.end(), [&](std::shared_ptr<CapabilityInfo> cap) {
122         if (cap != nullptr) {
123             devDhInfos.push_back({cap->GetDHId(), cap->GetDHType()});
124         }
125     });
126 
127     if (devDhInfos.empty()) {
128         DHLOGW("Can not get cap info from CapabilityInfo, try use meta info");
129         std::vector<std::shared_ptr<MetaCapabilityInfo>> metaCapInfos;
130         std::string udidHash = DHContext::GetInstance().GetUdidHashIdByUUID(GetUUID());
131         MetaInfoManager::GetInstance()->GetMetaCapInfosByUdidHash(udidHash, metaCapInfos);
132         std::for_each(metaCapInfos.begin(), metaCapInfos.end(), [&](std::shared_ptr<MetaCapabilityInfo> cap) {
133             if (cap != nullptr) {
134                 devDhInfos.push_back({cap->GetDHId(), cap->GetDHType()});
135             }
136         });
137     }
138 
139     if (devDhInfos.empty()) {
140         DHLOGE("Can not get cap info, uuid = %{public}s, deviceId = %{public}s", GetAnonyString(GetUUID()).c_str(),
141             GetAnonyString(deviceId).c_str());
142         return;
143     }
144 
145     for (const auto &info : devDhInfos) {
146         TaskParam taskParam = {
147             .networkId = GetNetworkId(),
148             .uuid = GetUUID(),
149             .dhId = info.first,
150             .dhType = info.second
151         };
152         auto task = TaskFactory::GetInstance().CreateTask(TaskType::DISABLE, taskParam, shared_from_this());
153         TaskExecutor::GetInstance().PushTask(task);
154     }
155 }
156 
CreateDisableSinkTask()157 void OffLineTask::CreateDisableSinkTask()
158 {
159     DHLOGI("CreateDisableSinkTask start");
160     DeviceInfo localDeviceInfo = GetLocalDeviceInfo();
161     std::vector<std::pair<std::string, DHType>> localMetaInfos;
162     std::vector<std::shared_ptr<MetaCapabilityInfo>> metaCapInfos;
163     MetaInfoManager::GetInstance()->GetMetaCapInfosByUdidHash(localDeviceInfo.udidHash, metaCapInfos);
164     std::for_each(metaCapInfos.begin(), metaCapInfos.end(), [&](std::shared_ptr<MetaCapabilityInfo> localMetaInfo) {
165         if (localMetaInfo != nullptr) {
166             localMetaInfos.push_back({localMetaInfo->GetDHId(), localMetaInfo->GetDHType()});
167         }
168     });
169     if (localMetaInfos.empty()) {
170         DHLOGE("Can not get localMetainfo.");
171         return;
172     }
173     for (const auto &localInfo : localMetaInfos) {
174         TaskParam taskParam = {
175             .networkId = localDeviceInfo.networkId,
176             .uuid = localDeviceInfo.uuid,
177             .udid = localDeviceInfo.udid,
178             .dhId = localInfo.first,
179             .dhType = localInfo.second
180         };
181         auto task = TaskFactory::GetInstance().CreateTask(TaskType::DISABLE, taskParam, shared_from_this());
182         TaskExecutor::GetInstance().PushTask(task);
183     }
184 }
185 
WaitDisableTaskFinish()186 void OffLineTask::WaitDisableTaskFinish()
187 {
188     DHLOGI("start wait disable task finish");
189     std::unique_lock<std::mutex> waitLock(unFinishTaskMtx_);
190     finishCondVar_.wait(waitLock, [&] { return this->unFinishChildrenTasks_.empty(); });
191     DHLOGI("all disable task finish");
192     DHContext::GetInstance().RemoveOnlineDeviceIdEntryByNetworkId(GetNetworkId());
193 }
194 
ClearOffLineInfo()195 void OffLineTask::ClearOffLineInfo()
196 {
197     DHLOGI("start clear resource when device offline, uuid = %{public}s", GetAnonyString(GetUUID()).c_str());
198     auto ret = CapabilityInfoManager::GetInstance()->RemoveCapabilityInfoInMem(GetDeviceIdByUUID(GetUUID()));
199     if (ret != DH_FWK_SUCCESS) {
200         DHLOGE("RemoveCapabilityInfoInMem failed, uuid = %{public}s, errCode = %{public}d",
201             GetAnonyString(GetUUID()).c_str(), ret);
202     }
203 }
204 
NotifyFatherFinish(std::string taskId)205 void OffLineTask::NotifyFatherFinish(std::string taskId)
206 {
207     {
208         std::lock_guard<std::mutex> lock(unFinishTaskMtx_);
209         this->unFinishChildrenTasks_.erase(taskId);
210     }
211     finishCondVar_.notify_all();
212 }
213 
AddChildrenTask(std::shared_ptr<Task> childrenTask)214 void OffLineTask::AddChildrenTask(std::shared_ptr<Task> childrenTask)
215 {
216     std::lock_guard<std::mutex> lock(unFinishTaskMtx_);
217     this->unFinishChildrenTasks_.insert(childrenTask->GetId());
218 }
219 
CreateMetaDisableTask()220 void OffLineTask::CreateMetaDisableTask()
221 {
222     DHLOGI("CreateMetaDisableTask, networkId = %{public}s, uuid = %{public}s", GetAnonyString(GetNetworkId()).c_str(),
223         GetAnonyString(GetUUID()).c_str());
224     uint16_t deviceType = DHContext::GetInstance().GetDeviceTypeByNetworkId(GetNetworkId());
225     if (deviceType != PHONE_TYPE) {
226         DHLOGI("offline device not phone, deviceType = %{public}d", deviceType);
227         return;
228     }
229     TaskParam taskParam = {
230         .networkId = GetNetworkId(),
231         .uuid = GetUUID(),
232         .dhId = "Modem_1234",
233         .dhType = DHType::MODEM
234     };
235     auto task = TaskFactory::GetInstance().CreateTask(TaskType::META_DISABLE, taskParam, shared_from_this());
236     TaskExecutor::GetInstance().PushTask(task);
237 }
238 } // namespace DistributedHardware
239 } // namespace OHOS
240