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 ¤tHandler;
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