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