• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 "event_handler_wrap.h"
17 
18 #include <cinttypes>
19 #include <chrono>
20 #include <mutex>
21 #include "cpp/mutex.h"
22 
23 #include "hilog_tag_wrapper.h"
24 
25 namespace OHOS {
26 namespace AAFwk {
27 namespace {
28 constexpr int64_t EVENT_TIME_DIFF = 200;  // ms
29 constexpr int64_t EVENT_TIME_CANCEL = 3000; // ms
GetCurrentTimeMillis()30 inline int64_t GetCurrentTimeMillis()
31 {
32     return std::chrono::duration_cast<std::chrono::milliseconds>(
33         std::chrono::steady_clock::now().time_since_epoch()).count();
34 }
35 }
EventHandlerWrap()36 EventHandlerWrap::EventHandlerWrap() : taskHandler_(TaskHandlerWrap::GetFfrtHandler())
37 {
38     eventMutex_ = std::make_unique<ffrt::mutex>();
39 }
40 
EventHandlerWrap(std::shared_ptr<TaskHandlerWrap> taskHandler)41 EventHandlerWrap::EventHandlerWrap(std::shared_ptr<TaskHandlerWrap> taskHandler)
42     : taskHandler_(taskHandler)
43 {
44     eventMutex_ = std::make_unique<ffrt::mutex>();
45 }
46 
47 EventHandlerWrap::~EventHandlerWrap() = default;
48 
ProcessEvent(const EventWrap & event)49 void EventHandlerWrap::ProcessEvent(const EventWrap &event)
50 {
51     if (eventCallback_) {
52         eventCallback_(event);
53     }
54 }
SendEvent(uint32_t eventId)55 bool EventHandlerWrap::SendEvent(uint32_t eventId)
56 {
57     return SendEvent(EventWrap(eventId, 0));
58 }
SendEvent(uint32_t eventId,int64_t delayMillis)59 bool EventHandlerWrap::SendEvent(uint32_t eventId, int64_t delayMillis)
60 {
61     return SendEvent(EventWrap(eventId, 0), delayMillis);
62 }
SendEvent(EventWrap event)63 bool EventHandlerWrap::SendEvent(EventWrap event)
64 {
65     return SendEvent(event, 0);
66 }
SendEvent(EventWrap event,int64_t delayMillis,bool forceInsert)67 bool EventHandlerWrap::SendEvent(EventWrap event, int64_t delayMillis, bool forceInsert)
68 {
69     if (!taskHandler_) {
70         return false;
71     }
72     auto eventStr = event.GetEventString();
73     std::lock_guard<ffrt::mutex> guard(*eventMutex_);
74     auto it  = eventMap_.find(eventStr);
75     if (it != eventMap_.end() && !forceInsert) {
76         return false;
77     }
78 
79     event.SetTimeout(delayMillis);
80     event.SetCreateTime(GetCurrentTimeMillis());
81     event.SetEventTask(taskHandler_->SubmitTaskJust([wthis = weak_from_this(), event]() {
82         auto timeCost = GetCurrentTimeMillis() - event.GetCreateTime();
83         if (timeCost - event.GetTimeout() > EVENT_TIME_DIFF) {
84             TAG_LOGW(AAFwkTag::DEFAULT, "createtime: %{public}" PRId64 ", timeout: %{public}" PRId64,
85                 event.GetCreateTime(), event.GetTimeout());
86         }
87         auto pthis = wthis.lock();
88         if (pthis) {
89             pthis->ProcessEvent(event);
90             pthis->RemoveEvent(event, false);
91         }
92     }, eventStr, delayMillis));
93 
94     if (it != eventMap_.end()) {
95         it->second = event;
96     } else {
97         eventMap_.emplace(eventStr, event);
98     }
99 
100     return true;
101 }
102 
RemoveEvent(uint32_t eventId,int64_t param)103 bool EventHandlerWrap::RemoveEvent(uint32_t eventId, int64_t param)
104 {
105     return RemoveEvent(EventWrap(eventId, param));
106 }
107 
RemoveEvent(uint32_t eventId,const std::string & taskName)108 bool EventHandlerWrap::RemoveEvent(uint32_t eventId, const std::string &taskName)
109 {
110     return RemoveEvent(EventWrap(eventId, taskName));
111 }
112 
RemoveEvent(EventWrap event,bool force)113 bool EventHandlerWrap::RemoveEvent(EventWrap event, bool force)
114 {
115     std::lock_guard<ffrt::mutex> guard(*eventMutex_);
116     auto it = eventMap_.find(event.GetEventString());
117     if (it == eventMap_.end()) {
118         TAG_LOGW(AAFwkTag::DEFAULT, "can't find event: %{public}s ", event.GetEventString().c_str());
119         return false;
120     }
121     auto isSame = it->second.IsSame(event);
122     const auto &origin = it->second;
123     auto timeCost = GetCurrentTimeMillis() - origin.GetCreateTime();
124     if (force && timeCost > EVENT_TIME_CANCEL) {
125         TAG_LOGW(AAFwkTag::DEFAULT, "event: %{public}s, timecost: %{public}" PRId64", delay: %{public}" PRId64,
126             origin.GetEventString().c_str(), timeCost, origin.GetTimeout());
127     }
128     if (force || isSame) {
129         auto result = it->second.GetEventTask().Cancel();
130         if (!result) {
131             TAG_LOGE(AAFwkTag::DEFAULT, "remove fail: %{public}s", event.GetEventString().c_str());
132         }
133         eventMap_.erase(it);
134         return true;
135     }
136     TAG_LOGD(AAFwkTag::DEFAULT, "force: %{public}d , IsSame: %{public}d", force, isSame);
137     return false;
138 }
139 }  // namespace AAFWK
140 }  // namespace OHOS