• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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.h"
17 
18 #include <unistd.h>
19 #include <sys/syscall.h>
20 #include "event_handler_utils.h"
21 #include "event_logger.h"
22 #ifdef HAS_HICHECKER_NATIVE_PART
23 #include "hichecker.h"
24 #endif // HAS_HICHECKER_NATIVE_PART
25 #ifdef FFRT_USAGE_ENABLE
26 #include "ffrt_inner.h"
27 #endif // FFRT_USAGE_ENABLE
28 #include "parameters.h"
29 #include "thread_local_data.h"
30 #include "event_hitrace_meter_adapter.h"
31 #include "ffrt_descriptor_listener.h"
32 
33 using namespace OHOS::HiviewDFX;
34 namespace OHOS {
35 namespace AppExecFwk {
36 namespace {
37 static constexpr int FFRT_SUCCESS = 0;
38 static constexpr int FFRT_ERROR = -1;
39 static constexpr int FFRT_TASK_REMOVE_FAIL = 1;
40 static constexpr uint64_t MILLISECONDS_TO_NANOSECONDS_RATIO = 1000000;
41 static const uint64_t PENDING_JOB_TIMEOUT[3] = {
42     system::GetIntParameter("const.sys.notification.pending_higher_event_vip", 4),
43     system::GetIntParameter("const.sys.notification.pending_higher_event_immediate", 40),
44     system::GetIntParameter("const.sys.notification.pending_higher_event_high", 400)
45 };
46 DEFINE_EH_HILOG_LABEL("EventHandler");
47 }
48 thread_local std::weak_ptr<EventHandler> EventHandler::currentEventHandler;
49 thread_local int32_t EventHandler::currentEventPriority = -1;
50 
Current()51 std::shared_ptr<EventHandler> EventHandler::Current()
52 {
53 #ifdef FFRT_USAGE_ENABLE
54     if (ffrt_this_task_get_id()) {
55         auto handler = ffrt_get_current_queue_eventhandler();
56         if (handler == nullptr) {
57             HILOGW("Current handler is null.");
58             return nullptr;
59         }
60         return *(reinterpret_cast<std::shared_ptr<EventHandler>*>(handler));
61     } else {
62         return currentEventHandler.lock();
63     }
64 #else
65     return currentEventHandler.lock();
66 #endif
67 }
68 
EventHandler(const std::shared_ptr<EventRunner> & runner)69 EventHandler::EventHandler(const std::shared_ptr<EventRunner> &runner) : eventRunner_(runner)
70 {
71     static std::atomic<uint64_t> handlerCount = 1;
72     handlerId_ = std::to_string(handlerCount.load()) + "_" + std::to_string(GetTimeStamp());
73     handlerCount.fetch_add(1);
74     EH_LOGI_LIMIT("Create eventHandler %{public}s", handlerId_.c_str());
75 }
76 
~EventHandler()77 EventHandler::~EventHandler()
78 {
79     HILOGI("~EventHandler enter %{public}s", handlerId_.c_str());
80     if (eventRunner_) {
81         HILOGD("eventRunner is alive");
82         /*
83          * This handler is finishing, need to remove all events belong to it.
84          * But events only have weak pointer of this handler,
85          * now weak pointer is invalid, so these events become orphans.
86          */
87 #ifdef FFRT_USAGE_ENABLE
88         if (eventRunner_->threadMode_ == ThreadMode::FFRT) {
89             eventRunner_->GetEventQueue()->RemoveOrphanByHandlerId(handlerId_);
90         } else {
91             eventRunner_->GetEventQueue()->RemoveOrphan();
92         }
93 #else
94         eventRunner_->GetEventQueue()->RemoveOrphan();
95 #endif
96     }
97 }
98 
SendEvent(InnerEvent::Pointer & event,int64_t delayTime,Priority priority)99 bool EventHandler::SendEvent(InnerEvent::Pointer &event, int64_t delayTime, Priority priority)
100 {
101     if (!event) {
102         HILOGE("Could not send an invalid event");
103         return false;
104     }
105 
106     InnerEvent::TimePoint now = InnerEvent::Clock::now();
107     event->SetSendTime(now);
108     event->SetSenderKernelThreadId(getproctid());
109     event->SetEventUniqueId();
110     if (delayTime > 0) {
111         event->SetHandleTime(now + std::chrono::milliseconds(delayTime));
112     } else {
113         event->SetHandleTime(now);
114     }
115     event->SetOwnerId(handlerId_);
116     event->SetDelayTime(delayTime);
117     event->SetOwner(shared_from_this());
118     // get traceId from event, if HiTraceChain::begin has been called, would get a valid trace id.
119     auto traceId = event->GetOrCreateTraceId();
120     // if traceId is valid, out put trace information
121     if (AllowHiTraceOutPut(traceId, event->HasWaiter())) {
122         HiTracePointerOutPut(traceId, event, "Send", HiTraceTracepointType::HITRACE_TP_CS);
123     }
124     HILOGD("Current event id is %{public}s .", (event->GetEventUniqueId()).c_str());
125     if (!eventRunner_) {
126         HILOGE("MUST Set event runner before sending events");
127         return false;
128     }
129     return eventRunner_->GetEventQueue()->Insert(event, priority);
130 }
131 
CreateTask(const Callback & callback,const std::string & name,Priority priority,const Caller & caller)132 InnerEvent::Pointer EventHandler::CreateTask(const Callback &callback, const std::string &name, Priority priority,
133     const Caller &caller)
134 {
135     if (!eventRunner_) {
136         HILOGE("MUST Set event runner before posting events");
137         return InnerEvent::Pointer(nullptr, nullptr);
138     }
139 
140     auto event = InnerEvent::Get(callback, name, caller);
141     if (!event) {
142         HILOGE("Get an invalid event");
143         return InnerEvent::Pointer(nullptr, nullptr);
144     }
145 
146     event->SetDelayTime(0);
147     event->SetOwnerId(handlerId_);
148     InnerEvent::TimePoint now = InnerEvent::Clock::now();
149     event->SetSendTime(now);
150     event->SetHandleTime(now);
151     event->SetSenderKernelThreadId(getproctid());
152     event->SetEventUniqueId();
153     event->SetOwner(shared_from_this());
154     auto traceId = event->GetOrCreateTraceId();
155     if (AllowHiTraceOutPut(traceId, event->HasWaiter())) {
156         HiTracePointerOutPut(traceId, event, "Send", HiTraceTracepointType::HITRACE_TP_CS);
157     }
158     return event;
159 }
160 
PostTaskAtFront(const Callback & callback,const std::string & name,Priority priority,const Caller & caller,bool noBarrier)161 bool EventHandler::PostTaskAtFront(const Callback &callback, const std::string &name, Priority priority,
162     const Caller &caller, bool noBarrier)
163 {
164     auto event = CreateTask(callback, name, priority, caller);
165     if (!event) {
166         return false;
167     }
168     HILOGD("Current front event id is %{public}s .", (event->GetEventUniqueId()).c_str());
169     eventRunner_->GetEventQueue()->Insert(event, priority, EventInsertType::AT_FRONT, noBarrier);
170     return true;
171 }
172 
PostTaskAtTail(const Callback & callback,const std::string & name,Priority priority,const Caller & caller,bool noBarrier)173 bool EventHandler::PostTaskAtTail(const Callback &callback, const std::string &name, Priority priority,
174     const Caller &caller, bool noBarrier)
175 {
176     auto event = CreateTask(callback, name, priority, caller);
177     if (!event) {
178         return false;
179     }
180     HILOGD("Current event id is %{public}s .", (event->GetEventUniqueId()).c_str());
181     eventRunner_->GetEventQueue()->Insert(event, priority, EventInsertType::AT_END, noBarrier);
182     return true;
183 }
184 
SendTimingEvent(InnerEvent::Pointer & event,int64_t taskTime,Priority priority)185 bool EventHandler::SendTimingEvent(InnerEvent::Pointer &event, int64_t taskTime, Priority priority)
186 {
187     InnerEvent::TimePoint nowSys = InnerEvent::Clock::now();
188     auto epoch = nowSys.time_since_epoch();
189     long nowSysTime = std::chrono::duration_cast<std::chrono::milliseconds>(epoch).count();
190     int64_t delayTime = taskTime - nowSysTime;
191     if (delayTime < 0) {
192         HILOGW("SendTime is before now systime, change to 0 delaytime Event");
193         return SendEvent(event, 0, priority);
194     }
195 
196     return SendEvent(event, delayTime, priority);
197 }
198 
SendSyncEvent(InnerEvent::Pointer & event,Priority priority)199 bool EventHandler::SendSyncEvent(InnerEvent::Pointer &event, Priority priority)
200 {
201     if ((!event) || (priority == Priority::IDLE)) {
202         HILOGE("Could not send an invalid event or idle event");
203         return false;
204     }
205 
206     if ((!eventRunner_) || (!eventRunner_->IsRunning())) {
207         HILOGE("MUST Set a running event runner before sending sync events");
208         return false;
209     }
210 
211     bool result = true;
212 #ifdef FFRT_USAGE_ENABLE
213     if ((ffrt_this_task_get_id() && eventRunner_->threadMode_ == ThreadMode::FFRT) ||
214         eventRunner_ == EventRunner::Current()) {
215         DistributeEvent(event);
216         return true;
217     }
218 
219     // get traceId from event, if HiTraceChain::begin has been called, would get a valid trace id.
220     auto spanId = event->GetOrCreateTraceId();
221 
222     if (eventRunner_->threadMode_ == ThreadMode::FFRT) {
223         event->SetSendTime(InnerEvent::Clock::now());
224         event->SetEventUniqueId();
225         event->SetHandleTime(InnerEvent::Clock::now());
226         event->SetOwnerId(handlerId_);
227         event->SetDelayTime(0);
228         event->SetOwner(shared_from_this());
229         result = eventRunner_->GetEventQueue()->InsertSyncEvent(event, priority);
230     } else {
231         // Create waiter, used to block.
232         auto waiter = event->CreateWaiter();
233         // Send this event as normal one.
234         if (!SendEvent(event, 0, priority)) {
235             HILOGE("SendEvent is failed");
236             return false;
237         }
238         // Wait until event is processed(recycled).
239         waiter->Wait();
240     }
241 #else
242     // If send a sync event in same event runner, distribute here.
243     if (eventRunner_ == EventRunner::Current()) {
244         DistributeEvent(event);
245         return true;
246     }
247 
248     // get traceId from event, if HiTraceChain::begin has been called, would get a valid trace id.
249     auto spanId = event->GetOrCreateTraceId();
250 
251     // Create waiter, used to block.
252     auto waiter = event->CreateWaiter();
253     // Send this event as normal one.
254     if (!SendEvent(event, 0, priority)) {
255         HILOGE("SendEvent is failed");
256         return false;
257     }
258     // Wait until event is processed(recycled).
259     waiter->Wait();
260 #endif
261     if ((spanId) && (spanId->IsValid())) {
262         HiTraceChain::Tracepoint(HiTraceTracepointType::HITRACE_TP_CR, *spanId, "event is processed");
263     }
264 
265     return result;
266 }
267 
RemoveAllEvents()268 void EventHandler::RemoveAllEvents()
269 {
270     HILOGD("RemoveAllEvents enter");
271     if (!eventRunner_) {
272         HILOGE("MUST Set event runner before removing all events");
273         return;
274     }
275 
276     eventRunner_->GetEventQueue()->Remove(shared_from_this());
277 }
278 
RemoveEvent(uint32_t innerEventId)279 void EventHandler::RemoveEvent(uint32_t innerEventId)
280 {
281     HILOGD("RemoveEvent enter");
282     if (!eventRunner_) {
283         HILOGE("MUST Set event runner before removing events by id");
284         return;
285     }
286 
287     eventRunner_->GetEventQueue()->Remove(shared_from_this(), innerEventId);
288 }
289 
RemoveEvent(uint32_t innerEventId,int64_t param)290 void EventHandler::RemoveEvent(uint32_t innerEventId, int64_t param)
291 {
292     HILOGD("RemoveEvent -- enter");
293     if (!eventRunner_) {
294         HILOGE("MUST Set event runner before removing events by id and param");
295         return;
296     }
297 
298     eventRunner_->GetEventQueue()->Remove(shared_from_this(), innerEventId, param);
299 }
300 
RemoveTask(const std::string & name)301 void EventHandler::RemoveTask(const std::string &name)
302 {
303     HILOGD("RemoveTask enter name %{public}s", name.c_str());
304     if (!eventRunner_) {
305         HILOGE("MUST Set event runner before removing events by task name %{public}s", name.c_str());
306         return;
307     }
308 
309     eventRunner_->GetEventQueue()->Remove(shared_from_this(), name);
310 }
311 
RemoveTaskWithRet(const std::string & name)312 int EventHandler::RemoveTaskWithRet(const std::string &name)
313 {
314     HILOGD("RemoveTaskWithRet enter");
315     if (!eventRunner_) {
316         HILOGE("MUST Ret Set event runner before removing events by task name");
317         return FFRT_TASK_REMOVE_FAIL;
318     }
319 
320     bool ret = eventRunner_->GetEventQueue()->Remove(shared_from_this(), name);
321     return ret ? FFRT_SUCCESS : FFRT_TASK_REMOVE_FAIL;
322 }
323 
AddFileDescriptorListener(int32_t fileDescriptor,uint32_t events,const std::shared_ptr<FileDescriptorListener> & listener,const std::string & taskName)324 ErrCode EventHandler::AddFileDescriptorListener(int32_t fileDescriptor, uint32_t events,
325     const std::shared_ptr<FileDescriptorListener> &listener, const std::string &taskName)
326 {
327     return AddFileDescriptorListener(fileDescriptor, events, listener, taskName, EventQueue::Priority::HIGH);
328 }
329 
AddFileDescriptorListener(int32_t fileDescriptor,uint32_t events,const std::shared_ptr<FileDescriptorListener> & listener,const std::string & taskName,EventQueue::Priority priority)330 ErrCode EventHandler::AddFileDescriptorListener(int32_t fileDescriptor, uint32_t events,
331     const std::shared_ptr<FileDescriptorListener> &listener, const std::string &taskName,
332     EventQueue::Priority priority)
333 {
334     HILOGD("enter");
335     if ((fileDescriptor < 0) || ((events & FILE_DESCRIPTOR_EVENTS_MASK) == 0) || (!listener)) {
336         HILOGE("%{public}d, %{public}u, %{public}s: Invalid parameter",
337                fileDescriptor, events, listener ? "valid" : "null");
338         return EVENT_HANDLER_ERR_INVALID_PARAM;
339     }
340 
341     if (!eventRunner_) {
342         HILOGE("MUST Set event runner before adding fd listener");
343         return EVENT_HANDLER_ERR_NO_EVENT_RUNNER;
344     }
345 
346     listener->SetOwner(shared_from_this());
347     return eventRunner_->GetEventQueue()->AddFileDescriptorListener(fileDescriptor, events, listener, taskName,
348         priority);
349 }
350 
RemoveAllFileDescriptorListeners()351 void EventHandler::RemoveAllFileDescriptorListeners()
352 {
353     HILOGD("enter");
354     if (!eventRunner_) {
355         HILOGE("MUST Set event runner before removing all fd listener");
356         return;
357     }
358 
359     eventRunner_->GetEventQueue()->RemoveFileDescriptorListener(shared_from_this());
360 }
361 
RemoveFileDescriptorListener(int32_t fileDescriptor)362 void EventHandler::RemoveFileDescriptorListener(int32_t fileDescriptor)
363 {
364     HILOGD("enter");
365     if (fileDescriptor < 0) {
366         HILOGE("fd %{public}d: Invalid parameter", fileDescriptor);
367         return;
368     }
369 
370     if (!eventRunner_) {
371         HILOGE("MUST Set event runner before removing fd listener by fd");
372         return;
373     }
374 
375     eventRunner_->GetEventQueue()->RemoveFileDescriptorListener(fileDescriptor);
376 }
377 
SetEventRunner(const std::shared_ptr<EventRunner> & runner)378 void EventHandler::SetEventRunner(const std::shared_ptr<EventRunner> &runner)
379 {
380     HILOGD("enter");
381     if (eventRunner_ == runner) {
382         return;
383     }
384 
385     if (eventRunner_) {
386         HILOGW("It is not recommended to change the event runner dynamically");
387 
388         // Remove all events and listeners from old event runner.
389         RemoveAllEvents();
390         RemoveAllFileDescriptorListeners();
391     }
392 
393     // Switch event runner.
394     eventRunner_ = runner;
395     return;
396 }
397 
DeliveryTimeAction(const InnerEvent::Pointer & event,InnerEvent::TimePoint nowStart)398 void EventHandler::DeliveryTimeAction(const InnerEvent::Pointer &event, InnerEvent::TimePoint nowStart)
399 {
400 #ifdef HAS_HICHECKER_NATIVE_PART
401     HILOGD("enter");
402     if (!HiChecker::NeedCheckSlowEvent()) {
403         return;
404     }
405     int64_t deliveryTimeout = eventRunner_->GetDeliveryTimeout();
406     if (deliveryTimeout > 0) {
407         std::string threadName = eventRunner_->GetRunnerThreadName();
408         std::string eventName = GetEventName(event);
409         int64_t threadId = getproctid();
410         std::string threadIdCharacter = std::to_string(threadId);
411         std::chrono::duration<double> deliveryTime = nowStart - event->GetSendTime();
412         std::string deliveryTimeCharacter = std::to_string((deliveryTime).count());
413         std::string deliveryTimeoutCharacter = std::to_string(deliveryTimeout);
414         std::string handOutTag = "threadId: " + threadIdCharacter + "," + "threadName: " + threadName + "," +
415             "eventName: " + eventName + "," + "deliveryTime: " + deliveryTimeCharacter + "," +
416             "deliveryTimeout: " + deliveryTimeoutCharacter;
417         if ((nowStart - std::chrono::milliseconds(deliveryTimeout)) > event->GetHandleTime()) {
418             HiChecker::NotifySlowEvent(handOutTag);
419             if (deliveryTimeoutCallback_) {
420                 deliveryTimeoutCallback_();
421             }
422         }
423     }
424 #endif // HAS_HICHECKER_NATIVE_PART
425 }
426 
DistributeTimeAction(const InnerEvent::Pointer & event,InnerEvent::TimePoint nowStart)427 void EventHandler::DistributeTimeAction(const InnerEvent::Pointer &event, InnerEvent::TimePoint nowStart)
428 {
429 #ifdef HAS_HICHECKER_NATIVE_PART
430     HILOGD("enter");
431     if (!HiChecker::NeedCheckSlowEvent()) {
432         return;
433     }
434     int64_t distributeTimeout = eventRunner_->GetDistributeTimeout();
435     if (distributeTimeout > 0) {
436         std::string threadName = eventRunner_->GetRunnerThreadName();
437         std::string eventName = GetEventName(event);
438         int64_t threadId = getproctid();
439         std::string threadIdCharacter = std::to_string(threadId);
440         InnerEvent::TimePoint nowEnd = InnerEvent::Clock::now();
441         std::chrono::duration<double> distributeTime = nowEnd - nowStart;
442         std::string distributeTimeCharacter = std::to_string((distributeTime).count());
443         std::string distributeTimeoutCharacter = std::to_string(distributeTimeout);
444         std::string executeTag = "threadId: " + threadIdCharacter + "," + "threadName: " + threadName + "," +
445             "eventName: " + eventName + "," + "distributeTime: " + distributeTimeCharacter + "," +
446             "distributeTimeout: " + distributeTimeoutCharacter;
447         if ((nowEnd - std::chrono::milliseconds(distributeTimeout)) > nowStart) {
448             HiChecker::NotifySlowEvent(executeTag);
449             if (distributeTimeoutCallback_) {
450                 distributeTimeoutCallback_();
451             }
452         }
453     }
454 #endif // HAS_HICHECKER_NATIVE_PART
455 }
456 
DistributeTimeoutHandler(const InnerEvent::TimePoint & beginTime)457 void EventHandler::DistributeTimeoutHandler(const InnerEvent::TimePoint& beginTime)
458 {
459     int64_t distributeTimeout = EventRunner::GetMainEventRunner()->GetTimeout();
460     if (distributeTimeout > 0) {
461         InnerEvent::TimePoint endTime = InnerEvent::Clock::now();
462         if ((endTime - std::chrono::milliseconds(distributeTimeout)) > beginTime &&
463             EventRunner::distributeCallback_) {
464             HILOGI("AppMainThread Callback.");
465             auto diff = endTime - beginTime;
466             int64_t durationTime = std::chrono::duration_cast<std::chrono::milliseconds>(diff).count();
467             EventRunner::distributeCallback_(durationTime);
468         }
469     }
470 }
471 
DistributeEvent(const InnerEvent::Pointer & event)472 void EventHandler::DistributeEvent(const InnerEvent::Pointer &event) __attribute__((no_sanitize("cfi")))
473 {
474     if (!event) {
475         HILOGE("Could not distribute an invalid event");
476         return;
477     }
478 
479     currentEventHandler = shared_from_this();
480     if (enableEventLog_) {
481         auto now = InnerEvent::Clock::now();
482         auto currentRunningInfo = "start at " + InnerEvent::DumpTimeToString(now) + "; " + event->Dump() +
483         eventRunner_->GetEventQueue()->DumpCurrentQueueSize();
484         HILOGD("%{public}s", currentRunningInfo.c_str());
485     }
486 
487     StartTraceAdapter(event);
488 
489     auto spanId = event->GetTraceId();
490     auto traceId = HiTraceChain::GetId();
491     bool allowTraceOutPut = AllowHiTraceOutPut(spanId, event->HasWaiter());
492     if (allowTraceOutPut) {
493         HiTraceChain::SetId(*spanId);
494         HiTracePointerOutPut(spanId, event, "Receive", HiTraceTracepointType::HITRACE_TP_SR);
495     }
496 
497     InnerEvent::TimePoint nowStart = InnerEvent::Clock::now();
498     DeliveryTimeAction(event, nowStart);
499     HILOGD("EventName is %{public}s, eventId is %{public}s priority %{public}d.", GetEventName(event).c_str(),
500         (event->GetEventUniqueId()).c_str(), event->GetEventPriority());
501 
502     SetCurrentEventPriority(event->GetEventPriority());
503     std::string eventName = GetEventName(event);
504     InnerEvent::TimePoint beginTime;
505     bool isAppMainThread = EventRunner::IsAppMainThread();
506     if (EventRunner::distributeBegin_ && isAppMainThread) {
507         beginTime = EventRunner::distributeBegin_(eventName);
508     }
509 
510     if (event->HasTask()) {
511         // Call task callback directly if contains a task.
512         HILOGD("excute event taskCallback");
513         (event->GetTaskCallback())();
514     } else {
515         // Otherwise let developers to handle it.
516         ProcessEvent(event);
517     }
518 
519     if (EventRunner::distributeBegin_ && EventRunner::distributeEnd_ && isAppMainThread) {
520         EventRunner::distributeEnd_(eventName, beginTime);
521         DistributeTimeoutHandler(beginTime);
522     }
523 
524     DistributeTimeAction(event, nowStart);
525 
526     if (allowTraceOutPut) {
527         HiTraceChain::Tracepoint(HiTraceTracepointType::HITRACE_TP_SS, *spanId, "Event Distribute over");
528         HiTraceChain::ClearId();
529         if (traceId.IsValid()) {
530             HiTraceChain::SetId(traceId);
531         }
532     }
533     if (enableEventLog_) {
534         auto now = InnerEvent::Clock::now();
535         HILOGD("end at %{public}s", InnerEvent::DumpTimeToString(now).c_str());
536     }
537     FinishTraceAdapter();
538 }
539 
HasPendingHigherEvent(int32_t priority)540 bool EventHandler::HasPendingHigherEvent(int32_t priority)
541 {
542     if (!eventRunner_ || !eventRunner_->GetEventQueue()) {
543         return false;
544     }
545     if (priority < static_cast<int32_t>(AppExecFwk::EventQueue::Priority::VIP) ||
546         priority > static_cast<int32_t>(AppExecFwk::EventQueue::Priority::IDLE)) {
547         priority = GetCurrentEventPriority();
548     }
549     if (priority <= static_cast<int32_t>(AppExecFwk::EventQueue::Priority::VIP)) {
550         return false;
551     }
552     InnerEvent::TimePoint now = InnerEvent::Clock::now();
553     for (int i = priority - 1; i >= static_cast<int32_t>(AppExecFwk::EventQueue::Priority::VIP); --i) {
554         auto eventHandleTime = eventRunner_->GetEventQueue()->GetQueueFirstEventHandleTime(i);
555         if (eventHandleTime == UINT64_MAX) {
556             continue;
557         }
558         if (priority == static_cast<int32_t>(AppExecFwk::EventQueue::Priority::IDLE)) {
559             return true;
560         }
561         if (eventHandleTime + PENDING_JOB_TIMEOUT[i] * MILLISECONDS_TO_NANOSECONDS_RATIO <=
562             static_cast<uint64_t>(now.time_since_epoch().count())) {
563             return true;
564         }
565     }
566     return false;
567 }
568 
SetCurrentEventPriority(int32_t priority)569 void EventHandler::SetCurrentEventPriority(int32_t priority)
570 {
571     currentEventPriority = priority;
572 }
573 
GetCurrentEventPriority()574 const int32_t &EventHandler::GetCurrentEventPriority()
575 {
576     return currentEventPriority;
577 }
578 
Dump(Dumper & dumper)579 void EventHandler::Dump(Dumper &dumper)
580 {
581     HILOGI("EventHandler start dumper!");
582     auto now = std::chrono::system_clock::now();
583     dumper.Dump(dumper.GetTag() + " EventHandler dump begin curTime: " +
584         InnerEvent::DumpTimeToString(now) + LINE_SEPARATOR);
585     if (eventRunner_ == nullptr) {
586         dumper.Dump(dumper.GetTag() + " event runner uninitialized!" + LINE_SEPARATOR);
587     } else {
588         eventRunner_->Dump(dumper);
589     }
590     HILOGI("EventHandler end dumper!");
591 }
592 
HasInnerEvent(uint32_t innerEventId)593 bool EventHandler::HasInnerEvent(uint32_t innerEventId)
594 {
595     if (!eventRunner_) {
596         HILOGE("event runner uninitialized!");
597         return false;
598     }
599     return eventRunner_->GetEventQueue()->HasInnerEvent(shared_from_this(), innerEventId);
600 }
601 
HasInnerEvent(int64_t param)602 bool EventHandler::HasInnerEvent(int64_t param)
603 {
604     if (!eventRunner_) {
605         HILOGE("event runner uninitialized!");
606         return false;
607     }
608     return eventRunner_->GetEventQueue()->HasInnerEvent(shared_from_this(), param);
609 }
610 
GetEventName(const InnerEvent::Pointer & event)611 std::string EventHandler::GetEventName(const InnerEvent::Pointer &event)
612 {
613     std::string eventName;
614     if (!event) {
615         HILOGW("event is nullptr");
616         return eventName;
617     }
618 
619     if (event->HasTask()) {
620         eventName = event->GetTaskName();
621     } else {
622         InnerEvent::EventId eventId = event->GetInnerEventIdEx();
623         if (eventId.index() == TYPE_U32_INDEX) {
624             eventName = std::to_string(std::get<uint32_t>(eventId));
625         } else {
626             eventName = std::get<std::string>(eventId);
627         }
628     }
629     return eventName;
630 }
631 
IsIdle()632 bool EventHandler::IsIdle()
633 {
634     return eventRunner_->GetEventQueue()->IsIdle();
635 }
636 
ProcessEvent(const InnerEvent::Pointer &)637 void EventHandler::ProcessEvent(const InnerEvent::Pointer &)
638 {}
639 
EnableEventLog(bool enableEventLog)640 void EventHandler::EnableEventLog(bool enableEventLog)
641 {
642     enableEventLog_ = enableEventLog;
643 }
644 
HasPreferEvent(int basePrio)645 bool EventHandler::HasPreferEvent(int basePrio)
646 {
647     return eventRunner_->GetEventQueue()->HasPreferEvent(basePrio);
648 }
649 
QueryPendingTaskInfo(int32_t fileDescriptor)650 PendingTaskInfo EventHandler::QueryPendingTaskInfo(int32_t fileDescriptor)
651 {
652     if (!eventRunner_) {
653         HILOGE("QueryPendingTaskInfo event runner uninitialized!");
654         return PendingTaskInfo();
655     }
656     return eventRunner_->GetEventQueue()->QueryPendingTaskInfo(fileDescriptor);
657 }
658 
TaskCancelAndWait()659 void EventHandler::TaskCancelAndWait()
660 {
661 #ifdef FFRT_USAGE_ENABLE
662     if (!eventRunner_) {
663         HILOGE("CancelAndWait error,event runner is nullptr");
664         return;
665     }
666     if (eventRunner_->threadMode_ == ThreadMode::FFRT) {
667         eventRunner_->GetEventQueue()->CancelAndWait();
668     }
669 #endif
670 }
671 
GetMainEventHandlerForFFRT()672 extern "C" void* GetMainEventHandlerForFFRT()
673 {
674     HILOGD("GetMainEventHandlerForFFRT enter");
675     static std::shared_ptr<OHOS::AppExecFwk::EventHandler> mainHandler =
676         std::make_shared<OHOS::AppExecFwk::EventHandler>(OHOS::AppExecFwk::EventRunner::GetMainEventRunner());
677     if (mainHandler == nullptr) {
678         HILOGW("GetMainEventHandlerForFFRT execute fail, mainHandler is nullptr");
679         return nullptr;
680     }
681     return &mainHandler;
682 }
683 
GetCurrentEventHandlerForFFRT()684 extern "C" void* GetCurrentEventHandlerForFFRT()
685 {
686     HILOGD("GetCurrentEventHandlerForFFRT enter");
687     thread_local std::shared_ptr<OHOS::AppExecFwk::EventHandler> currentHandler =
688         std::make_shared<OHOS::AppExecFwk::EventHandler>(OHOS::AppExecFwk::EventRunner::Current());
689     if (currentHandler == nullptr) {
690         HILOGW("GetCurrentEventHandlerForFFRT execute fail, currentHandler is nullptr");
691         return nullptr;
692     }
693     return &currentHandler;
694 }
695 
PostTaskByFFRT(void * handler,const std::function<void ()> & callback,const TaskOptions & task)696 extern "C" bool PostTaskByFFRT(void* handler, const std::function<void()>& callback, const TaskOptions &task)
697 {
698     HILOGD("PostTaskByFFRT enter");
699     if (handler == nullptr) {
700         HILOGW("PostTaskByFFRT execute fail, handler is nullptr");
701         return false;
702     }
703     std::shared_ptr<EventHandler>* ptr = reinterpret_cast<std::shared_ptr<EventHandler>*>(handler);
704     Caller caller = {};
705     caller.dfxName_ = task.dfxName_;
706     return (*ptr)->PostTask(callback, std::to_string(task.taskId_), task.delayTime_, task.priority_, caller);
707 }
708 
PostSyncTaskByFFRT(void * handler,const std::function<void ()> & callback,const std::string & name,EventQueue::Priority priority)709 extern "C" bool PostSyncTaskByFFRT(void* handler, const std::function<void()>& callback,
710     const std::string &name, EventQueue::Priority priority)
711 {
712     HILOGD("PostSyncTaskByFFRT enter");
713     if (handler == nullptr) {
714         HILOGW("PostSyncTaskByFFRT execute fail, handler is nullptr");
715         return false;
716     }
717     std::shared_ptr<EventHandler>* ptr = reinterpret_cast<std::shared_ptr<EventHandler>*>(handler);
718     return (*ptr)->PostSyncTask(callback, name, priority);
719 }
720 
RemoveTaskForFFRT(void * handler,const uintptr_t taskId)721 extern "C" int RemoveTaskForFFRT(void* handler, const uintptr_t taskId)
722 {
723     HILOGD("RemoveTaskForFFRT enter");
724     if (handler == nullptr) {
725         HILOGW("RemoveTaskForFFRT execute fail, handler is nullptr");
726         return FFRT_TASK_REMOVE_FAIL;
727     }
728     std::shared_ptr<EventHandler>* ptr = reinterpret_cast<std::shared_ptr<EventHandler>*>(handler);
729     return (*ptr)->RemoveTaskWithRet(std::to_string(taskId));
730 }
731 
RemoveAllTaskForFFRT(void * handler)732 extern "C" void RemoveAllTaskForFFRT(void* handler)
733 {
734     HILOGD("RemoveAllTaskForFFRT enter");
735     if (handler == nullptr) {
736         HILOGW("RemoveAllTaskForFFRT execute fail, handler is nullptr");
737         return;
738     }
739     std::shared_ptr<EventHandler>* ptr = reinterpret_cast<std::shared_ptr<EventHandler>*>(handler);
740     (*ptr)->RemoveAllEvents();
741 }
742 
AddFdListenerByFFRT(void * handler,uint32_t fd,uint32_t event,void * data,ffrt_poller_cb cb)743 extern "C" int AddFdListenerByFFRT(void* handler, uint32_t fd, uint32_t event, void* data, ffrt_poller_cb cb)
744 {
745     if (handler == nullptr) {
746         HILOGW("AddFdListenerByFFRT execute fail, handler is nullptr");
747         return FFRT_ERROR;
748     }
749 
750     auto listener = std::make_shared<FfrtDescriptorListener>(event, data, cb);
751     std::shared_ptr<EventHandler>* ptr = reinterpret_cast<std::shared_ptr<EventHandler>*>(handler);
752     if ((*ptr) == nullptr) {
753         HILOGW("AddFdListenerByFFRT execute failed");
754         return FFRT_ERROR;
755     }
756     uint32_t innerEvent = FfrtDescriptorListener::ConvertEvents(event);
757     std::string taskName = "FFRT_FD_" + std::to_string(fd);
758     ErrCode result = (*ptr)->AddFileDescriptorListener(fd, innerEvent, listener, taskName);
759     return (result == ERR_OK) ? FFRT_SUCCESS : FFRT_ERROR;
760 }
761 
RemoveFdListenerByFFRT(void * handler,uint32_t fd)762 extern "C" int RemoveFdListenerByFFRT(void* handler, uint32_t fd)
763 {
764     if (handler == nullptr) {
765         HILOGW("RemoveFdListenerByFFRT execute fail, handler is nullptr");
766         return FFRT_ERROR;
767     }
768 
769     std::shared_ptr<EventHandler>* ptr = reinterpret_cast<std::shared_ptr<EventHandler>*>(handler);
770     if ((*ptr) == nullptr) {
771         HILOGW("RemoveFdListenerByFFRT execute failed");
772         return FFRT_ERROR;
773     }
774     (*ptr)->RemoveFileDescriptorListener(fd);
775     return FFRT_SUCCESS;
776 }
777 }  // namespace AppExecFwk
778 }  // namespace OHOS
779