Flutter Engine
The Flutter Engine
message_loop_android.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "flutter/fml/platform/android/message_loop_android.h"
6
7#include <fcntl.h>
8#include <unistd.h>
9
10#include "flutter/fml/platform/linux/timerfd.h"
11
12namespace fml {
13
14static constexpr int kClockType = CLOCK_MONOTONIC;
15
16static ALooper* AcquireLooperForThread() {
17 ALooper* looper = ALooper_forThread();
18
19 if (looper == nullptr) {
20 // No looper has been configured for the current thread. Create one and
21 // return the same.
22 looper = ALooper_prepare(0);
23 }
24
25 // The thread already has a looper. Acquire a reference to the same and return
26 // it.
27 ALooper_acquire(looper);
28 return looper;
29}
30
31MessageLoopAndroid::MessageLoopAndroid()
32 : looper_(AcquireLooperForThread()),
34 FML_CHECK(looper_.is_valid());
35 FML_CHECK(timer_fd_.is_valid());
36
37 static const int kWakeEvents = ALOOPER_EVENT_INPUT;
38
39 ALooper_callbackFunc read_event_fd = [](int, int events, void* data) -> int {
40 if (events & kWakeEvents) {
41 reinterpret_cast<MessageLoopAndroid*>(data)->OnEventFired();
42 }
43 return 1; // continue receiving callbacks
44 };
45
46 int add_result = ::ALooper_addFd(looper_.get(), // looper
47 timer_fd_.get(), // fd
48 ALOOPER_POLL_CALLBACK, // ident
49 kWakeEvents, // events
50 read_event_fd, // callback
51 this // baton
52 );
54}
55
56MessageLoopAndroid::~MessageLoopAndroid() {
57 int remove_result = ::ALooper_removeFd(looper_.get(), timer_fd_.get());
58 FML_CHECK(remove_result == 1);
59}
60
62 FML_DCHECK(looper_.get() == ALooper_forThread());
63
64 running_ = true;
65
66 while (running_) {
67 int result = ::ALooper_pollOnce(-1, // infinite timeout
68 nullptr, // out fd,
69 nullptr, // out events,
70 nullptr // out data
71 );
72 if (result == ALOOPER_POLL_TIMEOUT || result == ALOOPER_POLL_ERROR) {
73 // This handles the case where the loop is terminated using ALooper APIs.
74 running_ = false;
75 }
76 }
77}
78
79void MessageLoopAndroid::Terminate() {
80 running_ = false;
81 ALooper_wake(looper_.get());
82}
83
84void MessageLoopAndroid::WakeUp(fml::TimePoint time_point) {
85 [[maybe_unused]] bool result = TimerRearm(timer_fd_.get(), time_point);
87}
88
89void MessageLoopAndroid::OnEventFired() {
90 if (TimerDrain(timer_fd_.get())) {
91 RunExpiredTasksNow();
92 }
93}
94
95} // namespace fml
GAsyncResult * result
#define FML_CHECK(condition)
Definition: logging.h:85
#define FML_DCHECK(condition)
Definition: logging.h:103
static int64_t add_result
Definition: ascii_trie.cc:9
static constexpr int kClockType
bool TimerRearm(int fd, fml::TimePoint time_point)
Rearms the timer to expire at the given time point.
Definition: timerfd.cc:38
static ALooper * AcquireLooperForThread()
bool TimerDrain(int fd)
Definition: timerfd.cc:59
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
int timerfd_create(int clockid, int flags)
Definition: timerfd.cc:19
#define TFD_NONBLOCK
Definition: timerfd.h:33
#define TFD_CLOEXEC
Definition: timerfd.h:32