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 "disable_task.h"
17
18 #include <pthread.h>
19
20 #include "ffrt.h"
21
22 #include "anonymous_string.h"
23 #include "capability_utils.h"
24 #include "component_manager.h"
25 #include "constants.h"
26 #include "dh_context.h"
27 #include "dh_utils_hitrace.h"
28 #include "dh_utils_tool.h"
29 #include "distributed_hardware_errno.h"
30 #include "distributed_hardware_log.h"
31 #include "offline_task.h"
32 #include "task_board.h"
33
34 namespace OHOS {
35 namespace DistributedHardware {
36 #undef DH_LOG_TAG
37 #define DH_LOG_TAG "DisableTask"
38
DisableTask(const std::string & networkId,const std::string & uuid,const std::string & udid,const std::string & dhId,const DHType dhType)39 DisableTask::DisableTask(const std::string &networkId, const std::string &uuid, const std::string &udid,
40 const std::string &dhId, const DHType dhType) : Task(networkId, uuid, udid, dhId, dhType)
41 {
42 SetTaskType(TaskType::DISABLE);
43 SetTaskSteps(std::vector<TaskStep> { TaskStep::DO_DISABLE });
44 DHLOGD("DisableTask id: %{public}s, networkId: %{public}s, dhId: %{public}s",
45 GetId().c_str(), GetAnonyString(networkId).c_str(), GetAnonyString(dhId).c_str());
46 }
47
~DisableTask()48 DisableTask::~DisableTask()
49 {
50 DHLOGD("id = %{public}s, uuid = %{public}s", GetId().c_str(), GetAnonyString(GetUUID()).c_str());
51 }
52
DoTask()53 void DisableTask::DoTask()
54 {
55 ffrt::submit([this]() { this->DoTaskInner(); });
56 }
57
DoTaskInner()58 void DisableTask::DoTaskInner()
59 {
60 int32_t ret = pthread_setname_np(pthread_self(), DISABLE_TASK_INNER);
61 if (ret != DH_FWK_SUCCESS) {
62 DHLOGE("DoTaskInner setname failed.");
63 }
64 DHLOGD("id = %{public}s, uuid = %{public}s, dhId = %{public}s", GetId().c_str(), GetAnonyString(GetUUID()).c_str(),
65 GetAnonyString(GetDhId()).c_str());
66 SetTaskState(TaskState::RUNNING);
67
68 /* trigger Unregister Distributed Hardware Task, sync function */
69 auto result = UnRegisterHardware();
70 if (result == DH_FWK_SUCCESS) {
71 std::string enabledDeviceKey = GetCapabilityKey(GetDeviceIdByUUID(GetUUID()), GetDhId());
72 TaskBoard::GetInstance().RemoveEnabledDevice(enabledDeviceKey);
73 }
74 auto state = (result == DH_FWK_SUCCESS) ? TaskState::SUCCESS : TaskState::FAIL;
75 SetTaskState(state);
76
77 DHLOGD("finish disable task, remove it, id = %{public}s", GetId().c_str());
78 std::string taskId = GetId();
79 std::shared_ptr<Task> father = GetFatherTask().lock();
80 TaskBoard::GetInstance().RemoveTask(taskId);
81 /* if finish task, notify father finish */
82 if (father != nullptr) {
83 auto offLineTask = std::static_pointer_cast<OffLineTask>(father);
84 offLineTask->NotifyFatherFinish(taskId);
85 }
86 }
87
UnRegisterHardware()88 int32_t DisableTask::UnRegisterHardware()
89 {
90 DHCompMgrTraceStart(GetAnonyString(GetNetworkId()), GetAnonyString(GetDhId()), DH_DISABLE_START);
91
92 int32_t ret = DH_FWK_SUCCESS;
93
94 // Determine whether it is an active disable
95 if (GetCallingUid() || GetCallingPid()) {
96 // It is an active disable
97 ret = DoActiveDisable();
98 } else {
99 // It is an auto disable
100 ret = DoAutoDisable();
101 }
102 DHLOGI("disable task %{public}s, id = %{public}s, uuid = %{public}s, dhId = %{public}s.",
103 (ret == DH_FWK_SUCCESS) ? "success" : "failed", GetId().c_str(), GetAnonyString(GetUUID()).c_str(),
104 GetAnonyString(GetDhId()).c_str());
105 DHTraceEnd();
106 return ret;
107 }
108
SetEffectSink(bool isEffect)109 void DisableTask::SetEffectSink(bool isEffect)
110 {
111 effectSink_ = isEffect;
112 }
113
GetEffectSink()114 bool DisableTask::GetEffectSink()
115 {
116 return effectSink_;
117 }
118
SetEffectSource(bool isEffect)119 void DisableTask::SetEffectSource(bool isEffect)
120 {
121 effectSource_ = isEffect;
122 }
123
GetEffectSource()124 bool DisableTask::GetEffectSource()
125 {
126 return effectSource_;
127 }
128
SetCallingUid(int32_t callingUid)129 void DisableTask::SetCallingUid(int32_t callingUid)
130 {
131 callingUid_ = callingUid;
132 }
133
GetCallingUid()134 int32_t DisableTask::GetCallingUid()
135 {
136 return callingUid_;
137 }
138
SetCallingPid(int32_t callingPid)139 void DisableTask::SetCallingPid(int32_t callingPid)
140 {
141 callingPid_ = callingPid;
142 }
143
GetCallingPid()144 int32_t DisableTask::GetCallingPid()
145 {
146 return callingPid_;
147 }
148
DoAutoDisable()149 int32_t DisableTask::DoAutoDisable()
150 {
151 bool disableSink = false;
152 bool disableSource = false;
153 int32_t ret = ComponentManager::GetInstance().CheckDemandStart(GetUUID(), GetDhType(), disableSink, disableSource);
154 if (ret != DH_FWK_SUCCESS) {
155 DHLOGE("CheckDemandStart failed!");
156 return ret;
157 }
158 if (DHContext::GetInstance().GetRealTimeOnlineDeviceCount() == 0 &&
159 DHContext::GetInstance().GetIsomerismConnectCount() == 0) {
160 DHDescriptor dhDescriptor {
161 .dhType = GetDhType(),
162 .id = GetDhId()
163 };
164 if (disableSink) {
165 ret = ComponentManager::GetInstance().ForceDisableSink(dhDescriptor);
166 if (ret != DH_FWK_SUCCESS) {
167 DHLOGE("DisableSink failed!");
168 }
169 }
170 if (disableSource) {
171 ret = ComponentManager::GetInstance().ForceDisableSource(GetNetworkId(), dhDescriptor);
172 if (ret != DH_FWK_SUCCESS) {
173 DHLOGE("DisableSource failed!");
174 }
175 }
176 }
177 return ret;
178 }
179
DoActiveDisable()180 int32_t DisableTask::DoActiveDisable()
181 {
182 int32_t ret = DH_FWK_SUCCESS;
183 DHDescriptor dhDescriptor {
184 .dhType = GetDhType(),
185 .id = GetDhId()
186 };
187 if (GetEffectSink()) {
188 ret = ComponentManager::GetInstance().DisableSink(dhDescriptor, GetCallingUid(), GetCallingPid());
189 if (ret != DH_FWK_SUCCESS) {
190 DHLOGE("DisableSink failed!");
191 }
192 }
193 if (GetEffectSource()) {
194 ret = ComponentManager::GetInstance().DisableSource(
195 GetNetworkId(), dhDescriptor, GetCallingUid(), GetCallingPid());
196 if (ret != DH_FWK_SUCCESS) {
197 DHLOGE("DisableSource failed!");
198 }
199 }
200 return ret;
201 }
202 } // namespace DistributedHardware
203 } // namespace OHOS
204