1 /*
2 * Copyright (c) 2022 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 "dms_callback_task.h"
17
18 #include "dtbschedmgr_log.h"
19 #include "distributed_sched_service.h"
20 #include "parcel_helper.h"
21
22 namespace OHOS {
23 namespace DistributedSchedule {
24 using namespace OHOS::AppExecFwk;
25
26 namespace {
27 constexpr int64_t CALLBACK_DELAY_TIME = 30000;
28 const std::string TAG = "DmsCallbackTask";
29 }
30
Init(const DmsCallbackTaskInitCallbackFunc & callback)31 void DmsCallbackTask::Init(const DmsCallbackTaskInitCallbackFunc& callback)
32 {
33 auto runner = EventRunner::Create("dsched_callback");
34 dmsCallbackHandler_ = std::make_shared<DmsCallbackHandler>(runner, shared_from_this(), callback);
35 }
36
GenerateTaskId()37 int64_t DmsCallbackTask::GenerateTaskId()
38 {
39 std::lock_guard<std::mutex> autoLock(taskMutex_);
40 int64_t currValue = currTaskId_.load(std::memory_order_relaxed);
41 if (currTaskId_++ == INT64_MAX) {
42 currTaskId_ = 1;
43 }
44 return currValue;
45 }
46
PushCallback(int64_t taskId,const sptr<IRemoteObject> & callback,const std::string & deviceId,LaunchType launchType,const OHOS::AAFwk::Want & want)47 int32_t DmsCallbackTask::PushCallback(int64_t taskId, const sptr<IRemoteObject>& callback,
48 const std::string& deviceId, LaunchType launchType, const OHOS::AAFwk::Want& want)
49 {
50 HILOGI("PushCallback taskId:%{public}" PRId64, taskId);
51 if (taskId <= 0) {
52 HILOGE("PushCallback taskId invalid!");
53 return INVALID_PARAMETERS_ERR;
54 }
55
56 if (launchType == LaunchType::FREEINSTALL_START) {
57 if (callback == nullptr) {
58 HILOGE("PushCallback callback null!");
59 return INVALID_PARAMETERS_ERR;
60 }
61 }
62
63 if (dmsCallbackHandler_ == nullptr) {
64 HILOGE("PushCallback not initialized!");
65 return INVALID_PARAMETERS_ERR;
66 }
67
68 std::lock_guard<std::mutex> autoLock(callbackMapMutex_);
69 auto iterTask = callbackMap_.find(taskId);
70 if (iterTask != callbackMap_.end()) {
71 HILOGE("PushCallback taskId:%{public}" PRId64 " exist!", taskId);
72 return INVALID_PARAMETERS_ERR;
73 }
74
75 bool ret = dmsCallbackHandler_->SendEvent(taskId, 0, CALLBACK_DELAY_TIME);
76 if (!ret) {
77 HILOGE("PushCallback SendEvent failed!");
78 return INVALID_PARAMETERS_ERR;
79 }
80
81 CallbackTaskItem item {
82 .callback = callback,
83 .taskId = taskId,
84 .launchType = launchType,
85 .deviceId = deviceId,
86 .want = want,
87 };
88 (void)callbackMap_.emplace(taskId, item);
89 return ERR_OK;
90 }
91
PopCallback(int64_t taskId)92 CallbackTaskItem DmsCallbackTask::PopCallback(int64_t taskId)
93 {
94 std::lock_guard<std::mutex> autoLock(callbackMapMutex_);
95 auto iter = callbackMap_.find(taskId);
96 CallbackTaskItem item = {};
97 if (iter == callbackMap_.end()) {
98 HILOGW("PopCallback not found taskId:%{public}" PRId64 "!", taskId);
99 return item;
100 }
101 item = iter->second;
102 (void)callbackMap_.erase(iter);
103 if (dmsCallbackHandler_ != nullptr) {
104 dmsCallbackHandler_->RemoveEvent(taskId);
105 }
106 return item;
107 }
108
PopContinuationMissionMap(int64_t taskId)109 void DmsCallbackTask::PopContinuationMissionMap(int64_t taskId)
110 {
111 std::lock_guard<std::mutex> autoLock(callbackMapMutex_);
112 uint32_t ret = continuationMissionMap_.erase(taskId);
113 if (ret != 1) {
114 HILOGW("GetContinuaionMissionId not found taskId:%{public}" PRId64 "!", taskId);
115 }
116 }
117
GetContinuaionMissionId(int64_t taskId)118 int64_t DmsCallbackTask::GetContinuaionMissionId(int64_t taskId)
119 {
120 if (taskId <= 0) {
121 return INVALID_PARAMETERS_ERR;
122 }
123
124 std::lock_guard<std::mutex> autoLock(callbackMapMutex_);
125 auto iter = continuationMissionMap_.find(taskId);
126 if (iter == continuationMissionMap_.end()) {
127 HILOGW("GetContinuaionMissionId not found taskId:%{public}" PRId64 "!", taskId);
128 return INVALID_PARAMETERS_ERR;
129 }
130 HILOGI("GetContinuaionMissionId end, taskId :%{public}" PRId64 ".", taskId);
131 return iter->second;
132 }
133
SetContinuationMissionMap(int64_t taskId,int32_t missionId)134 void DmsCallbackTask::SetContinuationMissionMap(int64_t taskId, int32_t missionId)
135 {
136 HILOGI("taskId = %{public}" PRId64 ", missionId = %{public}d.", taskId, missionId);
137 if (taskId <= 0 || missionId <= 0) {
138 HILOGD("param invalid");
139 return;
140 }
141 std::lock_guard<std::mutex> autoLock(callbackMapMutex_);
142 auto itreator = continuationMissionMap_.find(taskId);
143 if (itreator != continuationMissionMap_.end()) {
144 HILOGD("taskId = %{public}" PRId64 ".", taskId);
145 return;
146 }
147 continuationMissionMap_[taskId] = missionId;
148 }
149
GetLaunchType(int64_t taskId)150 LaunchType DmsCallbackTask::GetLaunchType(int64_t taskId)
151 {
152 if (taskId <= 0) {
153 HILOGD("GetLaunchType param taskId invalid");
154 return LaunchType::FREEINSTALL_START;
155 }
156 std::lock_guard<std::mutex> autoLock(callbackMapMutex_);
157 auto iterTask = callbackMap_.find(taskId);
158 if (iterTask == callbackMap_.end()) {
159 HILOGE("GetLaunchType not found taskId : %{public}" PRId64 "!", taskId);
160 return LaunchType::FREEINSTALL_START;
161 }
162 CallbackTaskItem item = iterTask->second;
163 return item.launchType;
164 }
165
NotifyDeviceOffline(const std::string & deviceId)166 void DmsCallbackTask::NotifyDeviceOffline(const std::string& deviceId)
167 {
168 HILOGI("%{public}s begin.", __func__);
169 std::lock_guard<std::mutex> autoLock(callbackMapMutex_);
170 for (auto it = callbackMap_.begin(); it != callbackMap_.end();) {
171 if (it->second.deviceId == deviceId) {
172 if (dmsCallbackHandler_ != nullptr) {
173 dmsCallbackHandler_->RemoveEvent(it->second.taskId);
174 }
175 DistributedSchedService::GetInstance().NotifyFreeInstallResult(it->second, DEVICE_OFFLINE_ERR);
176 it = callbackMap_.erase(it);
177 } else {
178 it++;
179 }
180 }
181 }
182
ProcessEvent(const InnerEvent::Pointer & event)183 void DmsCallbackTask::DmsCallbackHandler::ProcessEvent(const InnerEvent::Pointer& event)
184 {
185 if (event == nullptr) {
186 HILOGE("ProcessEvent event nullptr!");
187 return;
188 }
189
190 auto eventId = event->GetInnerEventId();
191 int64_t taskId = static_cast<int64_t>(eventId);
192 if (taskId <= 0) {
193 HILOGW("ProcessEvent taskId invalid!");
194 return;
195 }
196
197 if (callback_ != nullptr) {
198 callback_(taskId);
199 }
200 }
201 } // namespace DistributedSchedule
202 } // namespace OHOS
203