Skip to content

Commit c0ec254

Browse files
committed
Add android-glue.
1 parent 5c6017b commit c0ec254

File tree

3 files changed

+240
-1
lines changed

3 files changed

+240
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[workspace]
2-
32
members = [
3+
"android-glue",
44
"android-ndk-sys",
55
"android-ndk",
66
]

android-glue/Cargo.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[package]
2+
name = "android-glue"
3+
version = "0.1.0"
4+
authors = ["David Craven <[email protected]>"]
5+
edition = "2018"
6+
7+
[dependencies]
8+
android_logger = "0.8.6"
9+
android-ndk-sys = { path = "../android-ndk-sys", default-features = false }
10+
android-ndk = { path = "../android-ndk", default-features = false }
11+
crossbeam = "0.7.3"
12+
lazy_static = "1.4.0"
13+
libc = "0.2.66"
14+
log = "0.4.8"

android-glue/src/lib.rs

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
use android_logger::Config;
2+
use android_ndk::input_queue::InputQueue;
3+
use android_ndk::native_activity::NativeActivity;
4+
use android_ndk::native_window::NativeWindow;
5+
use android_ndk_sys::{AInputQueue, ANativeActivity, ANativeWindow, ARect};
6+
use crossbeam::queue::SegQueue;
7+
use lazy_static::lazy_static;
8+
use log::Level;
9+
use std::fs::File;
10+
use std::io::{BufRead, BufReader};
11+
use std::os::raw;
12+
use std::os::unix::prelude::*;
13+
use std::ptr::NonNull;
14+
use std::sync::Mutex;
15+
use std::thread;
16+
17+
lazy_static! {
18+
static ref NATIVE_WINDOW: Mutex<Option<NativeWindow>> = Default::default();
19+
static ref INPUT_QUEUE: Mutex<Option<InputQueue>> = Default::default();
20+
static ref EVENT_QUEUE: SegQueue<Event> = Default::default();
21+
}
22+
23+
static mut NATIVE_ACTIVITY: Option<NativeActivity> = None;
24+
25+
pub fn native_activity() -> &'static NativeActivity {
26+
unsafe { NATIVE_ACTIVITY.as_ref().unwrap() }
27+
}
28+
29+
pub fn native_window() -> &'static Mutex<Option<NativeWindow>> {
30+
&NATIVE_WINDOW
31+
}
32+
33+
pub fn input_queue() -> &'static Mutex<Option<InputQueue>> {
34+
&INPUT_QUEUE
35+
}
36+
37+
pub fn poll_events() -> Option<Event> {
38+
EVENT_QUEUE.pop().ok()
39+
}
40+
41+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
42+
pub enum Event {
43+
Start,
44+
Resume,
45+
//SaveInstanceState,
46+
Pause,
47+
Stop,
48+
Destroy,
49+
ConfigChanged,
50+
LowMemory,
51+
WindowFocusChanged,
52+
WindowCreated,
53+
WindowResized,
54+
WindowRedrawNeeded,
55+
WindowDestroyed,
56+
InputQueueCreated,
57+
InputQueueDestroyed,
58+
ContentRectChanged,
59+
}
60+
61+
pub unsafe fn init(
62+
activity: *mut ANativeActivity,
63+
_saved_state: *mut u8,
64+
_saved_state_size: usize,
65+
main: fn(),
66+
) {
67+
let mut activity = NonNull::new(activity).unwrap();
68+
let mut callbacks = activity.as_mut().callbacks.as_mut().unwrap();
69+
callbacks.onStart = Some(on_start);
70+
callbacks.onResume = Some(on_resume);
71+
callbacks.onSaveInstanceState = Some(on_save_instance_state);
72+
callbacks.onPause = Some(on_pause);
73+
callbacks.onStop = Some(on_stop);
74+
callbacks.onDestroy = Some(on_destroy);
75+
callbacks.onWindowFocusChanged = Some(on_window_focus_changed);
76+
callbacks.onNativeWindowCreated = Some(on_window_created);
77+
callbacks.onNativeWindowResized = Some(on_window_resized);
78+
callbacks.onNativeWindowRedrawNeeded = Some(on_window_redraw_needed);
79+
callbacks.onNativeWindowDestroyed = Some(on_window_destroyed);
80+
callbacks.onInputQueueCreated = Some(on_input_queue_created);
81+
callbacks.onInputQueueDestroyed = Some(on_input_queue_destroyed);
82+
callbacks.onContentRectChanged = Some(on_content_rect_changed);
83+
callbacks.onConfigurationChanged = Some(on_configuration_changed);
84+
callbacks.onLowMemory = Some(on_low_memory);
85+
let activity = NativeActivity::from_ptr(activity);
86+
NATIVE_ACTIVITY = Some(activity);
87+
88+
let mut logpipe: [RawFd; 2] = Default::default();
89+
libc::pipe(logpipe.as_mut_ptr());
90+
libc::dup2(logpipe[1], libc::STDOUT_FILENO);
91+
libc::dup2(logpipe[1], libc::STDERR_FILENO);
92+
thread::spawn(move || {
93+
android_logger::init_once(
94+
Config::default()
95+
.with_min_level(Level::Trace)
96+
.with_tag("RustStdoutStderr"),
97+
);
98+
let file = File::from_raw_fd(logpipe[0]);
99+
let mut reader = BufReader::new(file);
100+
let mut buffer = String::new();
101+
loop {
102+
buffer.clear();
103+
if let Ok(len) = reader.read_line(&mut buffer) {
104+
if len == 0 {
105+
break;
106+
} else {
107+
log::info!("{}", buffer);
108+
}
109+
}
110+
}
111+
});
112+
113+
thread::spawn(main);
114+
}
115+
116+
unsafe extern "C" fn on_start(_activity: *mut ANativeActivity) {
117+
log::trace!("on_start");
118+
EVENT_QUEUE.push(Event::Start);
119+
}
120+
121+
unsafe extern "C" fn on_resume(_activity: *mut ANativeActivity) {
122+
log::trace!("on_resume");
123+
EVENT_QUEUE.push(Event::Resume);
124+
}
125+
126+
unsafe extern "C" fn on_save_instance_state(
127+
_activity: *mut ANativeActivity,
128+
_out_size: *mut usize,
129+
) -> *mut raw::c_void {
130+
log::trace!("on_save_instance_state");
131+
// TODO
132+
//EVENT_QUEUE.push(Event::Resume);
133+
std::ptr::null_mut()
134+
}
135+
136+
unsafe extern "C" fn on_pause(_activity: *mut ANativeActivity) {
137+
log::trace!("on_pause");
138+
EVENT_QUEUE.push(Event::Pause);
139+
}
140+
141+
unsafe extern "C" fn on_stop(_activity: *mut ANativeActivity) {
142+
log::trace!("on_stop");
143+
EVENT_QUEUE.push(Event::Stop);
144+
}
145+
146+
unsafe extern "C" fn on_destroy(_activity: *mut ANativeActivity) {
147+
log::trace!("on_destroy");
148+
EVENT_QUEUE.push(Event::Destroy);
149+
}
150+
151+
unsafe extern "C" fn on_configuration_changed(_activity: *mut ANativeActivity) {
152+
log::trace!("on_configuration_changed");
153+
EVENT_QUEUE.push(Event::ConfigChanged);
154+
}
155+
156+
unsafe extern "C" fn on_low_memory(_activity: *mut ANativeActivity) {
157+
log::trace!("on_low_memory");
158+
EVENT_QUEUE.push(Event::LowMemory);
159+
}
160+
161+
unsafe extern "C" fn on_window_focus_changed(
162+
_activity: *mut ANativeActivity,
163+
_has_focus: raw::c_int,
164+
) {
165+
log::trace!("on_window_focus_changed");
166+
EVENT_QUEUE.push(Event::WindowFocusChanged);
167+
}
168+
169+
unsafe extern "C" fn on_window_created(
170+
_activity: *mut ANativeActivity,
171+
window: *mut ANativeWindow,
172+
) {
173+
log::trace!("on_window_created");
174+
*NATIVE_WINDOW.lock().unwrap() = Some(NativeWindow::from_ptr(NonNull::new(window).unwrap()));
175+
EVENT_QUEUE.push(Event::WindowCreated);
176+
}
177+
178+
unsafe extern "C" fn on_window_resized(
179+
_activity: *mut ANativeActivity,
180+
_window: *mut ANativeWindow,
181+
) {
182+
log::trace!("on_window_resized");
183+
EVENT_QUEUE.push(Event::WindowResized);
184+
}
185+
186+
unsafe extern "C" fn on_window_redraw_needed(
187+
_activity: *mut ANativeActivity,
188+
_window: *mut ANativeWindow,
189+
) {
190+
log::trace!("on_window_redraw_needed");
191+
EVENT_QUEUE.push(Event::WindowRedrawNeeded);
192+
}
193+
194+
unsafe extern "C" fn on_window_destroyed(
195+
_activity: *mut ANativeActivity,
196+
_window: *mut ANativeWindow,
197+
) {
198+
log::trace!("on_window_destroyed");
199+
EVENT_QUEUE.push(Event::WindowDestroyed);
200+
*NATIVE_WINDOW.lock().unwrap() = None;
201+
}
202+
203+
unsafe extern "C" fn on_input_queue_created(
204+
_activity: *mut ANativeActivity,
205+
queue: *mut AInputQueue,
206+
) {
207+
log::trace!("on_input_queue_created");
208+
*INPUT_QUEUE.lock().unwrap() = Some(InputQueue::from_ptr(NonNull::new(queue).unwrap()));
209+
EVENT_QUEUE.push(Event::InputQueueCreated);
210+
}
211+
212+
unsafe extern "C" fn on_input_queue_destroyed(
213+
_activity: *mut ANativeActivity,
214+
_queue: *mut AInputQueue,
215+
) {
216+
log::trace!("on_input_queue_destroyed");
217+
EVENT_QUEUE.push(Event::InputQueueDestroyed);
218+
*INPUT_QUEUE.lock().unwrap() = None;
219+
}
220+
221+
unsafe extern "C" fn on_content_rect_changed(_activity: *mut ANativeActivity, _rect: *const ARect) {
222+
log::trace!("on_content_rect_changed");
223+
EVENT_QUEUE.push(Event::ContentRectChanged);
224+
// TODO
225+
}

0 commit comments

Comments
 (0)