1686862fbSopenharmony_ci/*
2686862fbSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3686862fbSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4686862fbSopenharmony_ci * you may not use this file except in compliance with the License.
5686862fbSopenharmony_ci * You may obtain a copy of the License at
6686862fbSopenharmony_ci *
7686862fbSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8686862fbSopenharmony_ci *
9686862fbSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10686862fbSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11686862fbSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12686862fbSopenharmony_ci * See the License for the specific language governing permissions and
13686862fbSopenharmony_ci * limitations under the License.
14686862fbSopenharmony_ci */
15686862fbSopenharmony_ci
16686862fbSopenharmony_ci#include "dms_callback_task.h"
17686862fbSopenharmony_ci
18686862fbSopenharmony_ci#include "dtbschedmgr_log.h"
19686862fbSopenharmony_ci#include "distributed_sched_service.h"
20686862fbSopenharmony_ci#include "parcel_helper.h"
21686862fbSopenharmony_ci
22686862fbSopenharmony_cinamespace OHOS {
23686862fbSopenharmony_cinamespace DistributedSchedule {
24686862fbSopenharmony_ciusing namespace OHOS::AppExecFwk;
25686862fbSopenharmony_ci
26686862fbSopenharmony_cinamespace {
27686862fbSopenharmony_ciconstexpr int64_t CALLBACK_DELAY_TIME = 30000;
28686862fbSopenharmony_ciconst std::string TAG = "DmsCallbackTask";
29686862fbSopenharmony_ci}
30686862fbSopenharmony_ci
31686862fbSopenharmony_civoid DmsCallbackTask::Init(const DmsCallbackTaskInitCallbackFunc& callback)
32686862fbSopenharmony_ci{
33686862fbSopenharmony_ci    auto runner = EventRunner::Create("dsched_callback");
34686862fbSopenharmony_ci    dmsCallbackHandler_ = std::make_shared<DmsCallbackHandler>(runner, shared_from_this(), callback);
35686862fbSopenharmony_ci}
36686862fbSopenharmony_ci
37686862fbSopenharmony_ciint64_t DmsCallbackTask::GenerateTaskId()
38686862fbSopenharmony_ci{
39686862fbSopenharmony_ci    std::lock_guard<std::mutex> autoLock(taskMutex_);
40686862fbSopenharmony_ci    int64_t currValue = currTaskId_.load(std::memory_order_relaxed);
41686862fbSopenharmony_ci    if (currTaskId_++ == INT64_MAX) {
42686862fbSopenharmony_ci        currTaskId_ = 1;
43686862fbSopenharmony_ci    }
44686862fbSopenharmony_ci    return currValue;
45686862fbSopenharmony_ci}
46686862fbSopenharmony_ci
47686862fbSopenharmony_ciint32_t DmsCallbackTask::PushCallback(int64_t taskId, const sptr<IRemoteObject>& callback,
48686862fbSopenharmony_ci    const std::string& deviceId, LaunchType launchType, const OHOS::AAFwk::Want& want)
49686862fbSopenharmony_ci{
50686862fbSopenharmony_ci    HILOGI("PushCallback taskId:%{public}" PRId64, taskId);
51686862fbSopenharmony_ci    if (taskId <= 0) {
52686862fbSopenharmony_ci        HILOGE("PushCallback taskId invalid!");
53686862fbSopenharmony_ci        return INVALID_PARAMETERS_ERR;
54686862fbSopenharmony_ci    }
55686862fbSopenharmony_ci
56686862fbSopenharmony_ci    if (launchType == LaunchType::FREEINSTALL_START) {
57686862fbSopenharmony_ci        if (callback == nullptr) {
58686862fbSopenharmony_ci            HILOGE("PushCallback callback null!");
59686862fbSopenharmony_ci            return INVALID_PARAMETERS_ERR;
60686862fbSopenharmony_ci        }
61686862fbSopenharmony_ci    }
62686862fbSopenharmony_ci
63686862fbSopenharmony_ci    if (dmsCallbackHandler_ == nullptr) {
64686862fbSopenharmony_ci        HILOGE("PushCallback not initialized!");
65686862fbSopenharmony_ci        return INVALID_PARAMETERS_ERR;
66686862fbSopenharmony_ci    }
67686862fbSopenharmony_ci
68686862fbSopenharmony_ci    std::lock_guard<std::mutex> autoLock(callbackMapMutex_);
69686862fbSopenharmony_ci    auto iterTask = callbackMap_.find(taskId);
70686862fbSopenharmony_ci    if (iterTask != callbackMap_.end()) {
71686862fbSopenharmony_ci        HILOGE("PushCallback taskId:%{public}" PRId64 " exist!", taskId);
72686862fbSopenharmony_ci        return INVALID_PARAMETERS_ERR;
73686862fbSopenharmony_ci    }
74686862fbSopenharmony_ci
75686862fbSopenharmony_ci    bool ret = dmsCallbackHandler_->SendEvent(taskId, 0, CALLBACK_DELAY_TIME);
76686862fbSopenharmony_ci    if (!ret) {
77686862fbSopenharmony_ci        HILOGE("PushCallback SendEvent failed!");
78686862fbSopenharmony_ci        return INVALID_PARAMETERS_ERR;
79686862fbSopenharmony_ci    }
80686862fbSopenharmony_ci
81686862fbSopenharmony_ci    CallbackTaskItem item {
82686862fbSopenharmony_ci        .callback = callback,
83686862fbSopenharmony_ci        .taskId = taskId,
84686862fbSopenharmony_ci        .launchType = launchType,
85686862fbSopenharmony_ci        .deviceId = deviceId,
86686862fbSopenharmony_ci        .want = want,
87686862fbSopenharmony_ci    };
88686862fbSopenharmony_ci    (void)callbackMap_.emplace(taskId, item);
89686862fbSopenharmony_ci    return ERR_OK;
90686862fbSopenharmony_ci}
91686862fbSopenharmony_ci
92686862fbSopenharmony_ciCallbackTaskItem DmsCallbackTask::PopCallback(int64_t taskId)
93686862fbSopenharmony_ci{
94686862fbSopenharmony_ci    std::lock_guard<std::mutex> autoLock(callbackMapMutex_);
95686862fbSopenharmony_ci    auto iter = callbackMap_.find(taskId);
96686862fbSopenharmony_ci    CallbackTaskItem item = {};
97686862fbSopenharmony_ci    if (iter == callbackMap_.end()) {
98686862fbSopenharmony_ci        HILOGW("PopCallback not found taskId:%{public}" PRId64 "!", taskId);
99686862fbSopenharmony_ci        return item;
100686862fbSopenharmony_ci    }
101686862fbSopenharmony_ci    item = iter->second;
102686862fbSopenharmony_ci    (void)callbackMap_.erase(iter);
103686862fbSopenharmony_ci    if (dmsCallbackHandler_ != nullptr) {
104686862fbSopenharmony_ci        dmsCallbackHandler_->RemoveEvent(taskId);
105686862fbSopenharmony_ci    }
106686862fbSopenharmony_ci    return item;
107686862fbSopenharmony_ci}
108686862fbSopenharmony_ci
109686862fbSopenharmony_civoid DmsCallbackTask::PopContinuationMissionMap(int64_t taskId)
110686862fbSopenharmony_ci{
111686862fbSopenharmony_ci    std::lock_guard<std::mutex> autoLock(callbackMapMutex_);
112686862fbSopenharmony_ci    uint32_t ret = continuationMissionMap_.erase(taskId);
113686862fbSopenharmony_ci    if (ret != 1) {
114686862fbSopenharmony_ci        HILOGW("GetContinuaionMissionId not found taskId:%{public}" PRId64 "!", taskId);
115686862fbSopenharmony_ci    }
116686862fbSopenharmony_ci}
117686862fbSopenharmony_ci
118686862fbSopenharmony_ciint64_t DmsCallbackTask::GetContinuaionMissionId(int64_t taskId)
119686862fbSopenharmony_ci{
120686862fbSopenharmony_ci    if (taskId <= 0) {
121686862fbSopenharmony_ci        return INVALID_PARAMETERS_ERR;
122686862fbSopenharmony_ci    }
123686862fbSopenharmony_ci
124686862fbSopenharmony_ci    std::lock_guard<std::mutex> autoLock(callbackMapMutex_);
125686862fbSopenharmony_ci    auto iter = continuationMissionMap_.find(taskId);
126686862fbSopenharmony_ci    if (iter == continuationMissionMap_.end()) {
127686862fbSopenharmony_ci        HILOGW("GetContinuaionMissionId not found taskId:%{public}" PRId64 "!", taskId);
128686862fbSopenharmony_ci        return INVALID_PARAMETERS_ERR;
129686862fbSopenharmony_ci    }
130686862fbSopenharmony_ci    HILOGI("GetContinuaionMissionId end, taskId :%{public}" PRId64 ".", taskId);
131686862fbSopenharmony_ci    return iter->second;
132686862fbSopenharmony_ci}
133686862fbSopenharmony_ci
134686862fbSopenharmony_civoid DmsCallbackTask::SetContinuationMissionMap(int64_t taskId, int32_t missionId)
135686862fbSopenharmony_ci{
136686862fbSopenharmony_ci    HILOGI("taskId = %{public}" PRId64 ", missionId = %{public}d.", taskId, missionId);
137686862fbSopenharmony_ci    if (taskId <= 0 || missionId <= 0) {
138686862fbSopenharmony_ci        HILOGD("param invalid");
139686862fbSopenharmony_ci        return;
140686862fbSopenharmony_ci    }
141686862fbSopenharmony_ci    std::lock_guard<std::mutex> autoLock(callbackMapMutex_);
142686862fbSopenharmony_ci    auto itreator = continuationMissionMap_.find(taskId);
143686862fbSopenharmony_ci    if (itreator != continuationMissionMap_.end()) {
144686862fbSopenharmony_ci        HILOGD("taskId = %{public}" PRId64 ".", taskId);
145686862fbSopenharmony_ci        return;
146686862fbSopenharmony_ci    }
147686862fbSopenharmony_ci    continuationMissionMap_[taskId] = missionId;
148686862fbSopenharmony_ci}
149686862fbSopenharmony_ci
150686862fbSopenharmony_ciLaunchType DmsCallbackTask::GetLaunchType(int64_t taskId)
151686862fbSopenharmony_ci{
152686862fbSopenharmony_ci    if (taskId <= 0) {
153686862fbSopenharmony_ci        HILOGD("GetLaunchType param taskId invalid");
154686862fbSopenharmony_ci        return LaunchType::FREEINSTALL_START;
155686862fbSopenharmony_ci    }
156686862fbSopenharmony_ci    std::lock_guard<std::mutex> autoLock(callbackMapMutex_);
157686862fbSopenharmony_ci    auto iterTask = callbackMap_.find(taskId);
158686862fbSopenharmony_ci    if (iterTask == callbackMap_.end()) {
159686862fbSopenharmony_ci        HILOGE("GetLaunchType not found taskId : %{public}" PRId64 "!", taskId);
160686862fbSopenharmony_ci        return LaunchType::FREEINSTALL_START;
161686862fbSopenharmony_ci    }
162686862fbSopenharmony_ci    CallbackTaskItem item = iterTask->second;
163686862fbSopenharmony_ci    return item.launchType;
164686862fbSopenharmony_ci}
165686862fbSopenharmony_ci
166686862fbSopenharmony_civoid DmsCallbackTask::NotifyDeviceOffline(const std::string& deviceId)
167686862fbSopenharmony_ci{
168686862fbSopenharmony_ci    HILOGI("%{public}s begin.", __func__);
169686862fbSopenharmony_ci    std::lock_guard<std::mutex> autoLock(callbackMapMutex_);
170686862fbSopenharmony_ci    for (auto it = callbackMap_.begin(); it != callbackMap_.end();) {
171686862fbSopenharmony_ci        if (it->second.deviceId == deviceId) {
172686862fbSopenharmony_ci            if (dmsCallbackHandler_ != nullptr) {
173686862fbSopenharmony_ci                dmsCallbackHandler_->RemoveEvent(it->second.taskId);
174686862fbSopenharmony_ci            }
175686862fbSopenharmony_ci            DistributedSchedService::GetInstance().NotifyFreeInstallResult(it->second, DEVICE_OFFLINE_ERR);
176686862fbSopenharmony_ci            it = callbackMap_.erase(it);
177686862fbSopenharmony_ci        } else {
178686862fbSopenharmony_ci            it++;
179686862fbSopenharmony_ci        }
180686862fbSopenharmony_ci    }
181686862fbSopenharmony_ci}
182686862fbSopenharmony_ci
183686862fbSopenharmony_civoid DmsCallbackTask::DmsCallbackHandler::ProcessEvent(const InnerEvent::Pointer& event)
184686862fbSopenharmony_ci{
185686862fbSopenharmony_ci    if (event == nullptr) {
186686862fbSopenharmony_ci        HILOGE("ProcessEvent event nullptr!");
187686862fbSopenharmony_ci        return;
188686862fbSopenharmony_ci    }
189686862fbSopenharmony_ci
190686862fbSopenharmony_ci    auto eventId = event->GetInnerEventId();
191686862fbSopenharmony_ci    int64_t taskId = static_cast<int64_t>(eventId);
192686862fbSopenharmony_ci    if (taskId <= 0) {
193686862fbSopenharmony_ci        HILOGW("ProcessEvent taskId invalid!");
194686862fbSopenharmony_ci        return;
195686862fbSopenharmony_ci    }
196686862fbSopenharmony_ci
197686862fbSopenharmony_ci    if (callback_ != nullptr) {
198686862fbSopenharmony_ci        callback_(taskId);
199686862fbSopenharmony_ci    }
200686862fbSopenharmony_ci}
201686862fbSopenharmony_ci}  // namespace DistributedSchedule
202686862fbSopenharmony_ci}  // namespace OHOS
203