1 /*
2  * Copyright (c) 2024 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 "dsched_collaborate_callback_mgr.h"
17 
18 #include "distributed_sched_service.h"
19 #include "dtbschedmgr_log.h"
20 #include "parcel_helper.h"
21 
22 using namespace OHOS::AppExecFwk;
23 
24 namespace OHOS {
25 namespace DistributedSchedule {
26 namespace {
27 const std::string TAG = "DSchedCollaborationCallbackMgr";
28 const std::u16string DSCHED_EVENT_TOKEN = u"ohos.distributedSchedule.dschedeventlistener";
29 constexpr int32_t DSCHED_EVENT_CALLBACK = 0;
30 }
31 
Init()32 void DSchedCollaborationCallbackMgr::Init()
33 {
34     diedListener_ = new DistributedEventDiedListener();
35 }
36 
PushCallback(const sptr<IRemoteObject> & callback)37 bool DSchedCollaborationCallbackMgr::PushCallback(const sptr<IRemoteObject>& callback)
38 {
39     HILOGI("DSchedCollaborationCallbackMgr PushCallback start!");
40     if (diedListener_ == nullptr) {
41         HILOGE("DSchedCollaborationCallbackMgr is not init!");
42         return false;
43     }
44     if (callback == nullptr) {
45         HILOGE("callback null!");
46         return false;
47     }
48     std::lock_guard<std::mutex> autoLock(collaborateCbLock_);
49     std::vector<sptr<IRemoteObject>> vecCallback = collaborateCbArr_;
50     for (auto ele = collaborateCbArr_.begin(); ele != collaborateCbArr_.end(); ++ele) {
51         if ((*ele) == callback) {
52             HILOGW("callback already  exists!");
53             return false;
54         }
55     }
56     collaborateCbArr_.push_back(callback);
57     callback->AddDeathRecipient(diedListener_);
58 
59     std::vector<EventNotify> events;
60     if (DistributedSchedService::GetInstance().GetDSchedEventInfo(DMS_COLLABORATION, events) != ERR_OK) {
61         HILOGE("GetDSchedEventInfo fail, events size %{public}zu", events.size());
62     }
63     for (const auto &event : events) {
64         int32_t dSchedEventresult = NotifyDSchedEventForOneCB(callback, event);
65         if (dSchedEventresult != ERR_OK) {
66             HILOGE("Push continuation success, notify dms event result: %{public}d", dSchedEventresult);
67         }
68     }
69 
70     return true;
71 }
72 
GetCallback()73 std::vector<sptr<IRemoteObject>> DSchedCollaborationCallbackMgr::GetCallback()
74 {
75     std::lock_guard<std::mutex> autoLock(collaborateCbLock_);
76     return collaborateCbArr_;
77 }
78 
CleanupCallback(const sptr<IRemoteObject> & callback)79 bool DSchedCollaborationCallbackMgr::CleanupCallback(const sptr<IRemoteObject>& callback)
80 {
81     std::lock_guard<std::mutex> autoLock(collaborateCbLock_);
82     if (collaborateCbArr_.empty()) {
83         HILOGE("No need for cleaning!");
84         return false;
85     }
86     for (auto ele = collaborateCbArr_.begin(); ele != collaborateCbArr_.end(); ++ele) {
87         if ((*ele) == callback) {
88             collaborateCbArr_.erase(ele);
89             HILOGI("callback is exists, cleared successfully.");
90             return true;
91         }
92     }
93     HILOGI("callback is not exists!");
94     return false;
95 }
96 
NotifyDSchedEventForOneCB(const sptr<IRemoteObject> & cb,const EventNotify & event)97 int32_t DSchedCollaborationCallbackMgr::NotifyDSchedEventForOneCB(const sptr<IRemoteObject> &cb,
98     const EventNotify& event)
99 {
100     if (cb == nullptr) {
101         HILOGE("NotifyDSchedEventForOneCB input callback is null.");
102         return INVALID_PARAMETERS_ERR;
103     }
104 
105     MessageParcel data;
106     if (!data.WriteInterfaceToken(DSCHED_EVENT_TOKEN)) {
107         HILOGE("NotifyDSchedEventForOneCB write token failed");
108         return SEND_REQUEST_DEF_FAIL;
109     }
110     PARCEL_WRITE_HELPER_RET(data, Int32, event.eventResult_, SEND_REQUEST_DEF_FAIL);
111     PARCEL_WRITE_HELPER_RET(data, String, event.srcNetworkId_, SEND_REQUEST_DEF_FAIL);
112     PARCEL_WRITE_HELPER_RET(data, String, event.dstNetworkId_, SEND_REQUEST_DEF_FAIL);
113     PARCEL_WRITE_HELPER_RET(data, String, event.srcBundleName_, SEND_REQUEST_DEF_FAIL);
114     PARCEL_WRITE_HELPER_RET(data, String, event.srcModuleName_, SEND_REQUEST_DEF_FAIL);
115     PARCEL_WRITE_HELPER_RET(data, String, event.srcAbilityName_, SEND_REQUEST_DEF_FAIL);
116     PARCEL_WRITE_HELPER_RET(data, String, event.destBundleName_, SEND_REQUEST_DEF_FAIL);
117     PARCEL_WRITE_HELPER_RET(data, String, event.destModuleName_, SEND_REQUEST_DEF_FAIL);
118     PARCEL_WRITE_HELPER_RET(data, String, event.destAbilityName_, SEND_REQUEST_DEF_FAIL);
119     PARCEL_WRITE_HELPER_RET(data, Int32, event.dSchedEventType_, SEND_REQUEST_DEF_FAIL);
120     PARCEL_WRITE_HELPER_RET(data, Int32, event.state_, SEND_REQUEST_DEF_FAIL);
121 
122     MessageParcel reply;
123     MessageOption option;
124     int32_t ret = cb->SendRequest(DSCHED_EVENT_CALLBACK, data, reply, option);
125     HILOGI("NotifyDSchedEventListenerResult transact end, ret: %{public}d.", ret);
126     return ret;
127 }
128 
NotifyDSchedEventResult(int32_t resultCode,const EventNotify & event)129 int32_t DSchedCollaborationCallbackMgr::NotifyDSchedEventResult(int32_t resultCode, const EventNotify& event)
130 {
131     HILOGI("GetCallback IDSchedEventListener");
132     std::vector<sptr<IRemoteObject>> vecCallback = GetCallback();
133     if (vecCallback.empty()) {
134         HILOGD("No listening has been registered, no need to report events");
135         return INVALID_PARAMETERS_ERR;
136     }
137     bool isAllSuc = true;
138     for (auto callback = vecCallback.begin(); callback != vecCallback.end(); ++callback) {
139         int32_t ret = NotifyDSchedEventForOneCB(*callback, event);
140         if (ret != ERR_OK) {
141             HILOGE("NotifyDSchedEventForOneCB transact fail, ret: %{public}d", ret);
142             isAllSuc = isAllSuc && false;
143         }
144     }
145     if (!isAllSuc) {
146         HILOGE("NotifyDSchedEventListenerResult transact fail, isAllSuc: %{public}d", isAllSuc);
147         return SEND_REQUEST_DEF_FAIL;
148     }
149     HILOGI("NotifyDSchedEventResult transact ok.");
150     return ERR_OK;
151 }
152 } // namespace DistributedSchedule
153 } // namespace OHOS
154