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 "offline_task.h"
17
18 #include <pthread.h>
19 #include <thread>
20
21 #include "anonymous_string.h"
22 #include "capability_info_manager.h"
23 #include "constants.h"
24 #include "dh_utils_tool.h"
25 #include "distributed_hardware_errno.h"
26 #include "distributed_hardware_log.h"
27 #include "task_board.h"
28 #include "task_executor.h"
29 #include "task_factory.h"
30
31 namespace OHOS {
32 namespace DistributedHardware {
33 #undef DH_LOG_TAG
34 #define DH_LOG_TAG "OffLineTask"
35
OffLineTask(const std::string & networkId,const std::string & uuid,const std::string & dhId,const DHType dhType)36 OffLineTask::OffLineTask(const std::string &networkId, const std::string &uuid, const std::string &dhId,
37 const DHType dhType) : Task(networkId, uuid, dhId, dhType)
38 {
39 this->SetTaskType(TaskType::OFF_LINE);
40 this->SetTaskSteps({TaskStep::UNREGISTER_OFFLINE_DISTRIBUTED_HARDWARE, TaskStep::WAIT_UNREGISTGER_COMPLETE,
41 TaskStep::CLEAR_OFFLINE_INFO});
42 DHLOGD("id = %s, uuid = %s", GetId().c_str(), GetAnonyString(uuid).c_str());
43 }
44
~OffLineTask()45 OffLineTask::~OffLineTask()
46 {
47 DHLOGD("id = %s, uuid = %s", GetId().c_str(), GetAnonyString(GetUUID()).c_str());
48 }
49
DoTask()50 void OffLineTask::DoTask()
51 {
52 std::thread(&OffLineTask::DoTaskInner, this).detach();
53 }
54
DoTaskInner()55 void OffLineTask::DoTaskInner()
56 {
57 int32_t ret = pthread_setname_np(pthread_self(), OFFLINE_TASK_INNER);
58 if (ret != DH_FWK_SUCCESS) {
59 DHLOGE("DoTaskInner setname failed.");
60 }
61 DHLOGD("start offline task, id = %s, uuid = %s", GetId().c_str(), GetAnonyString(GetUUID()).c_str());
62 this->SetTaskState(TaskState::RUNNING);
63 for (const auto& step : this->GetTaskSteps()) {
64 switch (step) {
65 case TaskStep::UNREGISTER_OFFLINE_DISTRIBUTED_HARDWARE: {
66 CreateDisableTask();
67 break;
68 }
69 case TaskStep::WAIT_UNREGISTGER_COMPLETE: {
70 WaitDisableTaskFinish();
71 break;
72 }
73 case TaskStep::CLEAR_OFFLINE_INFO: {
74 ClearOffLineInfo();
75 break;
76 }
77 default: {
78 break;
79 }
80 }
81 }
82
83 this->SetTaskState(TaskState::SUCCESS);
84 DHLOGD("Finish OffLine task, remove it, id: %s", GetId().c_str());
85 TaskBoard::GetInstance().RemoveTask(this->GetId());
86 }
87
CreateDisableTask()88 void OffLineTask::CreateDisableTask()
89 {
90 DHLOGI("networkId = %s, uuid = %s", GetAnonyString(GetNetworkId()).c_str(), GetAnonyString(GetUUID()).c_str());
91 std::vector<std::shared_ptr<CapabilityInfo>> capabilityInfos;
92 CapabilityInfoManager::GetInstance()->GetCapabilitiesByDeviceId(GetDeviceIdByUUID(GetUUID()), capabilityInfos);
93 if (capabilityInfos.empty()) {
94 DHLOGE("capabilityInfos is empty, can not create disableTask, uuid = %s", GetAnonyString(GetUUID()).c_str());
95 return;
96 }
97 for (const auto &iter : capabilityInfos) {
98 if (iter == nullptr) {
99 DHLOGE("capabilityInfo is null");
100 continue;
101 }
102 TaskParam taskParam = {
103 .networkId = GetNetworkId(),
104 .uuid = GetUUID(),
105 .dhId = iter->GetDHId(),
106 .dhType = iter->GetDHType()
107 };
108 auto task = TaskFactory::GetInstance().CreateTask(TaskType::DISABLE, taskParam, shared_from_this());
109 TaskExecutor::GetInstance().PushTask(task);
110 }
111 }
112
WaitDisableTaskFinish()113 void OffLineTask::WaitDisableTaskFinish()
114 {
115 DHLOGI("start wait disable task finish");
116 std::unique_lock<std::mutex> waitLock(unFinishTaskMtx_);
117 finishCondVar_.wait(waitLock, [&] { return this->unFinishChildrenTasks_.empty(); });
118 DHLOGI("all disable task finish");
119 }
120
ClearOffLineInfo()121 void OffLineTask::ClearOffLineInfo()
122 {
123 DHLOGI("start clear resource when device offline, uuid = %s", GetAnonyString(GetUUID()).c_str());
124 auto ret = CapabilityInfoManager::GetInstance()->RemoveCapabilityInfoInMem(GetDeviceIdByUUID(GetUUID()));
125 if (ret != DH_FWK_SUCCESS) {
126 DHLOGE("RemoveCapabilityInfoInMem failed, uuid = %s, errCode = %d", GetAnonyString(GetUUID()).c_str(), ret);
127 }
128 }
129
NotifyFatherFinish(std::string taskId)130 void OffLineTask::NotifyFatherFinish(std::string taskId)
131 {
132 {
133 std::lock_guard<std::mutex> lock(unFinishTaskMtx_);
134 this->unFinishChildrenTasks_.erase(taskId);
135 }
136 finishCondVar_.notify_all();
137 }
138
AddChildrenTask(std::shared_ptr<Task> childrenTask)139 void OffLineTask::AddChildrenTask(std::shared_ptr<Task> childrenTask)
140 {
141 std::lock_guard<std::mutex> lock(unFinishTaskMtx_);
142 this->unFinishChildrenTasks_.insert(childrenTask->GetId());
143 }
144 } // namespace DistributedHardware
145 } // namespace OHOS
146