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