Compare commits
66 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 02021c912c | |||
| 10d95187c7 | |||
| 5fbc26c61f | |||
| bc177292d2 | |||
| 8d30454c8d | |||
| feff63ae78 | |||
| 48993acf58 | |||
| 7d73e57364 | |||
| 781e1fd658 | |||
| 16391c4956 | |||
| da29177b41 | |||
| b29162d149 | |||
| 3a2fa5d1fa | |||
| 66e3293f4d | |||
| d5ff06ffb2 | |||
| b7f01a43d9 | |||
| f673662316 | |||
| 5dab74466c | |||
| 11c3af686f | |||
| 58bc3f6de7 | |||
| 6ea3f82fb8 | |||
| fb9a9f15c8 | |||
| 3e95c428f5 | |||
| 5d78da7296 | |||
| b1a63aeee6 | |||
| 206c8e2c84 | |||
| a654f72f62 | |||
| b161b24ce4 | |||
| a735faa753 | |||
| 2a9ed44d93 | |||
| 3d1b1c5cb9 | |||
| 00b116bcfe | |||
| dfc58b49fb | |||
| ecd03edb1a | |||
| 04c9060329 | |||
| f22d8bbd30 | |||
| 93828a18a9 | |||
| 4818de6709 | |||
| 190a3b91e7 | |||
| f54eaa2997 | |||
| 7a77402279 | |||
| 0d0c10ebb2 | |||
| 5220d35373 | |||
| b05dcb6d44 | |||
| e4608b0791 | |||
| ce36c38934 | |||
| 7a49db4d61 | |||
| 73a1acb3c7 | |||
| b07717d8ac | |||
| 8601f28eba | |||
| 49c877085b | |||
| 9e3d8fd977 | |||
| 5a7bc64bb1 | |||
| 114e249cbd | |||
| 875952b2a9 | |||
| b1b7f49c7e | |||
| 19c989c640 | |||
| 6278b54494 | |||
| a73f9202d0 | |||
| bb8eeb705c | |||
| 1ca5f13874 | |||
| eda89d0e15 | |||
| a8e8017918 | |||
| a8c0e37d80 | |||
| 3f06bce6ce | |||
| 74b2f22494 |
@@ -0,0 +1,136 @@
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUSTFLAGS: "-C debuginfo=0 --deny warnings"
|
||||
RUSTDOCFLAGS: -Dwarnings
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# We need to support the same MSRV as Winit which we are currently
|
||||
# assuming will be bumped to 1.60.0 soon:
|
||||
# https://github.com/rust-windowing/winit/pull/2453
|
||||
rust_version: [1.60.0, stable]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: hecrj/setup-rust-action@v1
|
||||
with:
|
||||
rust-version: ${{ matrix.rust_version }}
|
||||
|
||||
- name: Install Rust targets
|
||||
run: >
|
||||
rustup target add
|
||||
aarch64-linux-android
|
||||
armv7-linux-androideabi
|
||||
x86_64-linux-android
|
||||
i686-linux-android
|
||||
|
||||
- name: Install cargo-ndk
|
||||
run: cargo install cargo-ndk
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
|
||||
- name: Setup Android SDK
|
||||
uses: android-actions/setup-android@v2
|
||||
|
||||
- name: Build game-activity
|
||||
working-directory: android-activity
|
||||
run: >
|
||||
cargo ndk
|
||||
-t arm64-v8a
|
||||
-t armeabi-v7a
|
||||
-t x86_64
|
||||
-t x86
|
||||
build --features game-activity
|
||||
|
||||
- name: Build native-activity
|
||||
working-directory: android-activity
|
||||
run: >
|
||||
cargo ndk
|
||||
-t arm64-v8a
|
||||
-t armeabi-v7a
|
||||
-t x86_64
|
||||
-t x86
|
||||
build --features native-activity
|
||||
|
||||
- name: Build agdk-mainloop example
|
||||
if: matrix.rust_version == 'stable'
|
||||
working-directory: examples/agdk-mainloop
|
||||
run: >
|
||||
cargo ndk
|
||||
-t arm64-v8a
|
||||
-t armeabi-v7a
|
||||
-t x86_64
|
||||
-t x86
|
||||
-o app/src/main/jniLibs/ -- build
|
||||
|
||||
- name: Build na-mainloop example
|
||||
if: matrix.rust_version == 'stable'
|
||||
working-directory: examples/na-mainloop
|
||||
run: >
|
||||
cargo ndk
|
||||
-t arm64-v8a
|
||||
-t armeabi-v7a
|
||||
-t x86_64
|
||||
-t x86
|
||||
-o app/src/main/jniLibs/ -- build
|
||||
|
||||
- name: Build agdk-egui example
|
||||
if: matrix.rust_version == 'stable'
|
||||
working-directory: examples/agdk-egui
|
||||
run: >
|
||||
cargo ndk
|
||||
-t arm64-v8a
|
||||
-t armeabi-v7a
|
||||
-t x86_64
|
||||
-t x86
|
||||
-o app/src/main/jniLibs/ -- build
|
||||
|
||||
- name: Build agdk-eframe example
|
||||
if: matrix.rust_version == 'stable'
|
||||
working-directory: examples/agdk-eframe
|
||||
run: >
|
||||
cargo ndk
|
||||
-t arm64-v8a
|
||||
-t armeabi-v7a
|
||||
-t x86_64
|
||||
-t x86
|
||||
-o app/src/main/jniLibs/ -- build
|
||||
|
||||
- name: Documentation
|
||||
run: >
|
||||
cargo ndk -t arm64-v8a doc --no-deps
|
||||
|
||||
format:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
components: rustfmt
|
||||
|
||||
- name: Format
|
||||
run: cargo fmt --all -- --check
|
||||
working-directory: android-activity
|
||||
|
||||
- name: Format agdk-egui example
|
||||
run: cargo fmt --all -- --check
|
||||
working-directory: examples/agdk-egui
|
||||
@@ -0,0 +1 @@
|
||||
target
|
||||
@@ -6,8 +6,13 @@ members = [
|
||||
exclude = [
|
||||
"examples/agdk-mainloop",
|
||||
"examples/agdk-winit-wgpu",
|
||||
"examples/agdk-eframe",
|
||||
"examples/agdk-egui",
|
||||
"examples/agdk-oboe",
|
||||
"examples/agdk-cpal",
|
||||
"examples/na-mainloop",
|
||||
"examples/na-winit-wgpu",
|
||||
"examples/na-subclass-jni"
|
||||
"examples/na-subclass-jni",
|
||||
"examples/na-openxr-info",
|
||||
"examples/na-openxr-wgpu"
|
||||
]
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# Changelog
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
|
||||
## [0.3] - 2022-09-15
|
||||
### Added
|
||||
- `show/hide_sot_input` API for being able to show/hide a soft keyboard (other IME still pending)
|
||||
- `set_window_flags()` API for setting WindowManager params
|
||||
### Changed
|
||||
- *Breaking*: Created extensible, `#[non_exhaustive]` `InputEvent` wrapper enum instead of exposing `ndk` type directly
|
||||
|
||||
## [0.2] - 2022-08-25
|
||||
### Added
|
||||
- Emit an `InputAvailable` event for new input with `NativeActivity` and `GameActivity`
|
||||
enabling gui apps that don't render continuously
|
||||
- Oboe and Cpal audio examples added
|
||||
- `AndroidApp` is now `Send` + `Sync`
|
||||
### Changed
|
||||
- *Breaking*: updates to `ndk 0.7` and `ndk-sys 0.4`
|
||||
- *Breaking*: `AndroidApp::config()` now returns a clonable `ConfigurationRef` instead of a deep `Configuration` copy
|
||||
### Removed
|
||||
- The `NativeWindowRef` wrapper struct was removed since `NativeWindow` now implements `Clone` and `Drop` in `ndk 0.7`
|
||||
- *Breaking*: The `FdEvent` and `Error` enum values were removed from `PollEvents`
|
||||
|
||||
## [0.1.1] - 2022-07-04
|
||||
### Changed
|
||||
- Documentation fixes
|
||||
|
||||
## [0.1] - 2022-07-04
|
||||
### Added
|
||||
- Initial release
|
||||
@@ -1,11 +1,12 @@
|
||||
[package]
|
||||
name = "android-activity"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
edition = "2021"
|
||||
keywords = ["android", "ndk"]
|
||||
readme = "../README.md"
|
||||
homepage = "https://github.com/rib/android-activity"
|
||||
repository = "https://github.com/rib/android-activity"
|
||||
documentation = "https://docs.rs/android-activity"
|
||||
description = "Glue for building Rust applications on Android with NativeActivity or GameActivity"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
@@ -15,7 +16,7 @@ license = "MIT OR Apache-2.0"
|
||||
# are actually mutually exclusive.
|
||||
#
|
||||
# In general it's only the final application crate that needs
|
||||
# to decide in a backend.
|
||||
# to decide on a backend.
|
||||
default=[]
|
||||
game-activity = []
|
||||
native-activity = []
|
||||
@@ -23,13 +24,13 @@ native-activity = []
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
jni-sys = "0.3"
|
||||
ndk = { version = "0.6" }
|
||||
ndk-sys = { version = "0.3" }
|
||||
ndk-context = { version = "0.1" }
|
||||
ndk = "0.7"
|
||||
ndk-sys = "0.4"
|
||||
ndk-context = "0.1"
|
||||
android-properties = "0.2"
|
||||
num_enum = "0.5"
|
||||
bitflags = "1.3"
|
||||
libc = "0.2.84"
|
||||
libc = "0.2"
|
||||
|
||||
[build-dependencies]
|
||||
cc = { version = "1.0", features = ["parallel"] }
|
||||
@@ -40,4 +41,6 @@ targets = [
|
||||
"armv7-linux-androideabi",
|
||||
"i686-linux-android",
|
||||
"x86_64-linux-android",
|
||||
]
|
||||
]
|
||||
|
||||
rustdoc-args = ["--cfg", "docsrs" ]
|
||||
@@ -29,11 +29,15 @@ fn build_glue_for_game_activity() {
|
||||
.extra_warnings(false)
|
||||
.cpp_link_stdlib("c++_static")
|
||||
.compile("libnative_app_glue.a");
|
||||
|
||||
// We need to link to both c++_static and c++abi for the static C++ library.
|
||||
// Ideally we'd link directly to libc++.a.
|
||||
println!("cargo:rustc-link-lib=c++abi");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
#[cfg(feature="game-activity")]
|
||||
#[cfg(feature = "game-activity")]
|
||||
build_glue_for_game_activity();
|
||||
#[cfg(feature="native-activity")]
|
||||
#[cfg(feature = "native-activity")]
|
||||
build_glue_for_native_activity();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,6 +449,31 @@ void android_app_set_motion_event_filter(struct android_app* app,
|
||||
pthread_mutex_unlock(&app->mutex);
|
||||
}
|
||||
|
||||
bool android_app_input_available_wake_up(struct android_app* app) {
|
||||
pthread_mutex_lock(&app->mutex);
|
||||
// TODO: use atomic ops for this
|
||||
bool available = app->inputAvailableWakeUp;
|
||||
app->inputAvailableWakeUp = false;
|
||||
pthread_mutex_unlock(&app->mutex);
|
||||
return available;
|
||||
}
|
||||
|
||||
// NB: should be called with the android_app->mutex held already
|
||||
static void notifyInput(struct android_app* android_app) {
|
||||
// Don't spam the mainloop with wake ups if we've already sent one
|
||||
if (android_app->inputSwapPending) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (android_app->looper != NULL) {
|
||||
LOGV("Input Notify: %p", android_app);
|
||||
// for the app thread to know why it received the wake() up
|
||||
android_app->inputAvailableWakeUp = true;
|
||||
android_app->inputSwapPending = true;
|
||||
ALooper_wake(android_app->looper);
|
||||
}
|
||||
}
|
||||
|
||||
static bool onTouchEvent(GameActivity* activity,
|
||||
const GameActivityMotionEvent* event,
|
||||
const GameActivityHistoricalPointerAxes* historical,
|
||||
@@ -486,12 +511,15 @@ static bool onTouchEvent(GameActivity* activity,
|
||||
} else {
|
||||
inputBuffer->motionEvents[new_ix].historicalCount = 0;
|
||||
}
|
||||
|
||||
notifyInput(android_app);
|
||||
} else {
|
||||
LOGW_ONCE("Motion event will be dropped because the number of unconsumed motion"
|
||||
" events exceeded NATIVE_APP_GLUE_MAX_NUM_MOTION_EVENTS (%d). Consider setting"
|
||||
" NATIVE_APP_GLUE_MAX_NUM_MOTION_EVENTS_OVERRIDE to a larger value",
|
||||
NATIVE_APP_GLUE_MAX_NUM_MOTION_EVENTS);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
return true;
|
||||
}
|
||||
@@ -512,6 +540,9 @@ struct android_input_buffer* android_app_swap_input_buffers(
|
||||
NATIVE_APP_GLUE_MAX_INPUT_BUFFERS;
|
||||
}
|
||||
|
||||
android_app->inputSwapPending = false;
|
||||
android_app->inputAvailableWakeUp = false;
|
||||
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
|
||||
return inputBuffer;
|
||||
@@ -547,6 +578,8 @@ static bool onKey(GameActivity* activity, const GameActivityKeyEvent* event) {
|
||||
memcpy(&inputBuffer->keyEvents[new_ix], event,
|
||||
sizeof(GameActivityKeyEvent));
|
||||
++inputBuffer->keyEventsCount;
|
||||
|
||||
notifyInput(android_app);
|
||||
} else {
|
||||
LOGW_ONCE("Key event will be dropped because the number of unconsumed key events exceeded"
|
||||
" NATIVE_APP_GLUE_MAX_NUM_KEY_EVENTS (%d). Consider setting"
|
||||
|
||||
@@ -295,6 +295,26 @@ struct android_app {
|
||||
android_key_event_filter keyEventFilter;
|
||||
android_motion_event_filter motionEventFilter;
|
||||
|
||||
// When new input is received we set both of these flags and use the looper to
|
||||
// wake up the application mainloop.
|
||||
//
|
||||
// To avoid spamming the mainloop with wake ups from lots of input though we
|
||||
// don't sent a wake up if the inputSwapPending flag is already set. (i.e.
|
||||
// we already expect input to be processed in a finite amount of time due to
|
||||
// our previous wake up)
|
||||
//
|
||||
// When a wake up is received then we will check this flag (clearing it
|
||||
// at the same time). If it was set then an InputAvailable event is sent to
|
||||
// the application - which should lead to all input being processed within
|
||||
// a finite amount of time.
|
||||
//
|
||||
// The next time android_app_swap_input_buffers is called, both flags will be
|
||||
// cleared.
|
||||
//
|
||||
// NB: both of these should only be read with the app mutex held
|
||||
bool inputAvailableWakeUp;
|
||||
bool inputSwapPending;
|
||||
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
@@ -507,6 +527,10 @@ void android_app_set_key_event_filter(struct android_app* app,
|
||||
void android_app_set_motion_event_filter(struct android_app* app,
|
||||
android_motion_event_filter filter);
|
||||
|
||||
/**
|
||||
* Determines if a looper wake up was due to new input becoming available
|
||||
*/
|
||||
bool android_app_input_available_wake_up(struct android_app* app);
|
||||
|
||||
void GameActivity_onCreate_C(GameActivity* activity, void* savedState,
|
||||
size_t savedStateSize);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test -z "${ANDROID_NDK_ROOT}"; then
|
||||
export ANDROID_NDK_ROOT=${ANDROID_NDK_HOME}
|
||||
fi
|
||||
SYSROOT="${ANDROID_NDK_ROOT}"/toolchains/llvm/prebuilt/linux-x86_64/sysroot/
|
||||
if ! test -d $SYSROOT; then
|
||||
SYSROOT="${ANDROID_NDK_ROOT}"/toolchains/llvm/prebuilt/windows-x86_64/sysroot/
|
||||
@@ -8,7 +11,7 @@ fi
|
||||
while read ARCH && read TARGET ; do
|
||||
|
||||
# --module-raw-line 'use '
|
||||
bindgen game-activity-ffi.h -o src/game-activity/ffi_$ARCH.rs \
|
||||
bindgen game-activity-ffi.h -o src/game_activity/ffi_$ARCH.rs \
|
||||
--blocklist-item 'JNI\w+' \
|
||||
--blocklist-item 'C?_?JNIEnv' \
|
||||
--blocklist-item '_?JavaVM' \
|
||||
@@ -30,7 +33,7 @@ while read ARCH && read TARGET ; do
|
||||
-Igame-activity-csrc \
|
||||
--sysroot="$SYSROOT" --target=$TARGET
|
||||
|
||||
bindgen native-activity-ffi.h -o src/native-activity/ffi_$ARCH.rs \
|
||||
bindgen native-activity-ffi.h -o src/native_activity/ffi_$ARCH.rs \
|
||||
--blocklist-item 'JNI\w+' \
|
||||
--blocklist-item 'C?_?JNIEnv' \
|
||||
--blocklist-item '_?JavaVM' \
|
||||
|
||||
@@ -86,20 +86,33 @@ static void print_cur_config(struct android_app* android_app) {
|
||||
AConfiguration_getUiModeNight(android_app->config));
|
||||
}
|
||||
|
||||
void android_app_attach_input_queue_looper(struct android_app* android_app) {
|
||||
if (android_app->inputQueue != NULL) {
|
||||
LOGV("Attaching input queue to looper");
|
||||
AInputQueue_attachLooper(android_app->inputQueue,
|
||||
android_app->looper, LOOPER_ID_INPUT, NULL,
|
||||
&android_app->inputPollSource);
|
||||
}
|
||||
}
|
||||
|
||||
void android_app_detach_input_queue_looper(struct android_app* android_app) {
|
||||
if (android_app->inputQueue != NULL) {
|
||||
LOGV("Detaching input queue from looper");
|
||||
AInputQueue_detachLooper(android_app->inputQueue);
|
||||
}
|
||||
}
|
||||
|
||||
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) {
|
||||
switch (cmd) {
|
||||
case APP_CMD_INPUT_CHANGED:
|
||||
LOGV("APP_CMD_INPUT_CHANGED\n");
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
if (android_app->inputQueue != NULL) {
|
||||
//AInputQueue_detachLooper(android_app->inputQueue);
|
||||
android_app_detach_input_queue_looper(android_app);
|
||||
}
|
||||
android_app->inputQueue = android_app->pendingInputQueue;
|
||||
if (android_app->inputQueue != NULL) {
|
||||
//LOGV("Attaching input queue to looper");
|
||||
//AInputQueue_attachLooper(android_app->inputQueue,
|
||||
// android_app->looper, LOOPER_ID_INPUT, NULL,
|
||||
// &android_app->inputPollSource);
|
||||
android_app_attach_input_queue_looper(android_app);
|
||||
}
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
|
||||
@@ -331,6 +331,9 @@ void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd);
|
||||
*/
|
||||
void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd);
|
||||
|
||||
void android_app_attach_input_queue_looper(struct android_app* android_app);
|
||||
void android_app_detach_input_queue_looper(struct android_app* android_app);
|
||||
|
||||
/**
|
||||
* Dummy function that used to be used to prevent the linker from stripping app
|
||||
* glue code. No longer necessary, since __attribute__((visibility("default")))
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
use core::fmt;
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use ndk::configuration::{
|
||||
Configuration, Keyboard, KeysHidden, LayoutDir, NavHidden, Navigation, Orientation, ScreenLong,
|
||||
ScreenSize, Touchscreen, UiModeNight, UiModeType,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ConfigurationRef {
|
||||
config: Arc<RwLock<Configuration>>,
|
||||
}
|
||||
impl PartialEq for ConfigurationRef {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
if Arc::ptr_eq(&self.config, &other.config) {
|
||||
true
|
||||
} else {
|
||||
let other_guard = other.config.read().unwrap();
|
||||
self.config.read().unwrap().eq(&*other_guard)
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Eq for ConfigurationRef {}
|
||||
unsafe impl Send for ConfigurationRef {}
|
||||
unsafe impl Sync for ConfigurationRef {}
|
||||
|
||||
impl fmt::Debug for ConfigurationRef {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.config.read().unwrap().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfigurationRef {
|
||||
pub(crate) fn new(config: Configuration) -> Self {
|
||||
Self {
|
||||
config: Arc::new(RwLock::new(config)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn replace(&self, src: Configuration) {
|
||||
self.config.write().unwrap().copy(&src);
|
||||
}
|
||||
|
||||
// Returns a deep copy of the full application configuration
|
||||
pub fn copy(&self) -> Configuration {
|
||||
let mut dest = Configuration::new();
|
||||
dest.copy(&self.config.read().unwrap());
|
||||
dest
|
||||
}
|
||||
/// Returns the country code, as a [`String`] of two characters, if set
|
||||
pub fn country(&self) -> Option<String> {
|
||||
self.config.read().unwrap().country()
|
||||
}
|
||||
|
||||
/// Returns the screen density in dpi.
|
||||
///
|
||||
/// On some devices it can return values outside of the density enum.
|
||||
pub fn density(&self) -> Option<u32> {
|
||||
self.config.read().unwrap().density()
|
||||
}
|
||||
|
||||
/// Returns the keyboard type.
|
||||
pub fn keyboard(&self) -> Keyboard {
|
||||
self.config.read().unwrap().keyboard()
|
||||
}
|
||||
|
||||
/// Returns keyboard visibility/availability.
|
||||
pub fn keys_hidden(&self) -> KeysHidden {
|
||||
self.config.read().unwrap().keys_hidden()
|
||||
}
|
||||
|
||||
/// Returns the language, as a `String` of two characters, if a language is set
|
||||
pub fn language(&self) -> Option<String> {
|
||||
self.config.read().unwrap().language()
|
||||
}
|
||||
|
||||
/// Returns the layout direction
|
||||
pub fn layout_direction(&self) -> LayoutDir {
|
||||
self.config.read().unwrap().layout_direction()
|
||||
}
|
||||
|
||||
/// Returns the mobile country code.
|
||||
pub fn mcc(&self) -> i32 {
|
||||
self.config.read().unwrap().mcc()
|
||||
}
|
||||
|
||||
/// Returns the mobile network code, if one is defined
|
||||
pub fn mnc(&self) -> Option<i32> {
|
||||
self.config.read().unwrap().mnc()
|
||||
}
|
||||
|
||||
pub fn nav_hidden(&self) -> NavHidden {
|
||||
self.config.read().unwrap().nav_hidden()
|
||||
}
|
||||
|
||||
pub fn navigation(&self) -> Navigation {
|
||||
self.config.read().unwrap().navigation()
|
||||
}
|
||||
|
||||
pub fn orientation(&self) -> Orientation {
|
||||
self.config.read().unwrap().orientation()
|
||||
}
|
||||
|
||||
pub fn screen_height_dp(&self) -> Option<i32> {
|
||||
self.config.read().unwrap().screen_height_dp()
|
||||
}
|
||||
|
||||
pub fn screen_width_dp(&self) -> Option<i32> {
|
||||
self.config.read().unwrap().screen_width_dp()
|
||||
}
|
||||
|
||||
pub fn screen_long(&self) -> ScreenLong {
|
||||
self.config.read().unwrap().screen_long()
|
||||
}
|
||||
|
||||
#[cfg(feature = "api-level-30")]
|
||||
pub fn screen_round(&self) -> ScreenRound {
|
||||
self.config.read().unwrap().screen_round()
|
||||
}
|
||||
|
||||
pub fn screen_size(&self) -> ScreenSize {
|
||||
self.config.read().unwrap().screen_size()
|
||||
}
|
||||
|
||||
pub fn sdk_version(&self) -> i32 {
|
||||
self.config.read().unwrap().sdk_version()
|
||||
}
|
||||
|
||||
pub fn smallest_screen_width_dp(&self) -> Option<i32> {
|
||||
self.config.read().unwrap().smallest_screen_width_dp()
|
||||
}
|
||||
|
||||
pub fn touchscreen(&self) -> Touchscreen {
|
||||
self.config.read().unwrap().touchscreen()
|
||||
}
|
||||
|
||||
pub fn ui_mode_night(&self) -> UiModeNight {
|
||||
self.config.read().unwrap().ui_mode_night()
|
||||
}
|
||||
|
||||
pub fn ui_mode_type(&self) -> UiModeType {
|
||||
self.config.read().unwrap().ui_mode_type()
|
||||
}
|
||||
}
|
||||
@@ -15,8 +15,7 @@
|
||||
use jni_sys::*;
|
||||
use ndk_sys::AAssetManager;
|
||||
use ndk_sys::ANativeWindow;
|
||||
use ndk_sys::{ALooper, ALooper_callbackFunc, AConfiguration};
|
||||
|
||||
use ndk_sys::{AConfiguration, ALooper, ALooper_callbackFunc};
|
||||
|
||||
#[cfg(all(
|
||||
any(target_os = "android", feature = "test"),
|
||||
@@ -31,4 +30,4 @@ include!("ffi_aarch64.rs");
|
||||
include!("ffi_i686.rs");
|
||||
|
||||
#[cfg(all(any(target_os = "android", feature = "test"), target_arch = "x86_64"))]
|
||||
include!("ffi_x86_64.rs");
|
||||
include!("ffi_x86_64.rs");
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
// The `Class` was also bound differently to `android-ndk-rs` considering how the class is defined
|
||||
// by masking bits from the `Source`.
|
||||
|
||||
use crate::game_activity::ffi::{GameActivityKeyEvent, GameActivityMotionEvent};
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
use std::{convert::TryInto, ops::Deref};
|
||||
use crate::game_activity::ffi::{GameActivityMotionEvent, GameActivityKeyEvent};
|
||||
|
||||
use bitflags::bitflags;
|
||||
|
||||
@@ -25,7 +25,7 @@ use bitflags::bitflags;
|
||||
#[non_exhaustive]
|
||||
pub enum InputEvent {
|
||||
MotionEvent(MotionEvent),
|
||||
KeyEvent(KeyEvent)
|
||||
KeyEvent(KeyEvent),
|
||||
}
|
||||
|
||||
/// An enum representing the source of an [`MotionEvent`] or [`KeyEvent`]
|
||||
@@ -83,7 +83,7 @@ pub enum Class {
|
||||
Pointer,
|
||||
Trackball,
|
||||
Position,
|
||||
Joystick
|
||||
Joystick,
|
||||
}
|
||||
|
||||
impl From<i32> for Class {
|
||||
@@ -95,7 +95,7 @@ impl From<i32> for Class {
|
||||
SourceFlags::TRACKBALL => Class::Trackball,
|
||||
SourceFlags::POSITION => Class::Position,
|
||||
SourceFlags::JOYSTICK => Class::Joystick,
|
||||
_ => Class::None
|
||||
_ => Class::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -183,7 +183,7 @@ impl MetaState {
|
||||
/// javadoc](https://developer.android.com/reference/android/view/MotionEvent).
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MotionEvent {
|
||||
ga_event: GameActivityMotionEvent
|
||||
ga_event: GameActivityMotionEvent,
|
||||
}
|
||||
|
||||
impl Deref for MotionEvent {
|
||||
@@ -433,10 +433,7 @@ impl MotionEvent {
|
||||
if index >= self.pointer_count() {
|
||||
panic!("Pointer index {} is out of bounds", index);
|
||||
}
|
||||
Pointer {
|
||||
event: self,
|
||||
index,
|
||||
}
|
||||
Pointer { event: self, index }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -987,7 +984,7 @@ impl ExactSizeIterator for HistoricalPointersIter<'_> {
|
||||
/// javadoc](https://developer.android.com/reference/android/view/KeyEvent).
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct KeyEvent {
|
||||
ga_event: GameActivityKeyEvent
|
||||
ga_event: GameActivityKeyEvent,
|
||||
}
|
||||
|
||||
impl Deref for KeyEvent {
|
||||
@@ -1307,7 +1304,6 @@ pub enum Keycode {
|
||||
}
|
||||
|
||||
impl KeyEvent {
|
||||
|
||||
pub(crate) fn new(ga_event: GameActivityKeyEvent) -> Self {
|
||||
Self { ga_event }
|
||||
}
|
||||
@@ -1445,7 +1441,6 @@ impl KeyEventFlags {
|
||||
}
|
||||
|
||||
impl KeyEvent {
|
||||
|
||||
/// Flags associated with this [`KeyEvent`].
|
||||
///
|
||||
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#akeyevent_getflags)
|
||||
@@ -1462,4 +1457,4 @@ impl KeyEvent {
|
||||
pub fn meta_state(&self) -> MetaState {
|
||||
MetaState(self.metaState as u32)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,34 @@
|
||||
#![cfg(feature="game-activity")]
|
||||
#![cfg(feature = "game-activity")]
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Deref;
|
||||
use std::os::raw;
|
||||
use std::ptr::NonNull;
|
||||
use std::sync::Arc;
|
||||
use std::sync::RwLock;
|
||||
use std::time::Duration;
|
||||
use std::{thread, ptr};
|
||||
use std::os::unix::prelude::*;
|
||||
use std::ptr::NonNull;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::time::Duration;
|
||||
use std::{ptr, thread};
|
||||
|
||||
use log::{Level, error, trace};
|
||||
use log::{error, trace, Level};
|
||||
|
||||
use jni_sys::*;
|
||||
|
||||
use ndk_sys::{ALooper_wake};
|
||||
use ndk_sys::ALooper_wake;
|
||||
use ndk_sys::{ALooper, ALooper_pollAll};
|
||||
|
||||
use ndk::asset::AssetManager;
|
||||
use ndk::configuration::Configuration;
|
||||
use ndk::looper::{FdEvent};
|
||||
use ndk::native_window::NativeWindow;
|
||||
|
||||
use crate::{MainEvent, Rect, PollEvent, AndroidApp, NativeWindowRef};
|
||||
use crate::{util, AndroidApp, ConfigurationRef, MainEvent, PollEvent, Rect, WindowManagerFlags};
|
||||
|
||||
mod ffi;
|
||||
|
||||
pub mod input;
|
||||
use input::{MotionEvent, KeyEvent, Axis, InputEvent};
|
||||
|
||||
use input::{Axis, InputEvent, KeyEvent, MotionEvent};
|
||||
|
||||
// The only time it's safe to update the android_app->savedState pointer is
|
||||
// while handling a SaveState event, so this API is only exposed for those
|
||||
@@ -42,12 +40,11 @@ pub struct StateSaver<'a> {
|
||||
|
||||
impl<'a> StateSaver<'a> {
|
||||
pub fn store(&self, state: &'a [u8]) {
|
||||
|
||||
// android_native_app_glue specifically expects savedState to have been allocated
|
||||
// via libc::malloc since it will automatically handle freeing the data once it
|
||||
// has been handed over to the Java Activity / main thread.
|
||||
unsafe {
|
||||
let app_ptr = self.app.ptr.as_ptr();
|
||||
let app_ptr = self.app.native_app.as_ptr();
|
||||
|
||||
// In case the application calls store() multiple times for some reason we
|
||||
// make sure to free any pre-existing state...
|
||||
@@ -72,7 +69,7 @@ impl<'a> StateSaver<'a> {
|
||||
}
|
||||
|
||||
(*app_ptr).savedState = buf;
|
||||
(*app_ptr).savedStateSize = state.len() as u64;
|
||||
(*app_ptr).savedStateSize = state.len() as ffi::size_t;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,9 +81,12 @@ pub struct StateLoader<'a> {
|
||||
impl<'a> StateLoader<'a> {
|
||||
pub fn load(&self) -> Option<Vec<u8>> {
|
||||
unsafe {
|
||||
let app_ptr = self.app.ptr.as_ptr();
|
||||
let app_ptr = self.app.native_app.as_ptr();
|
||||
if (*app_ptr).savedState != ptr::null_mut() && (*app_ptr).savedStateSize > 0 {
|
||||
let buf: &mut [u8] = std::slice::from_raw_parts_mut((*app_ptr).savedState.cast(), (*app_ptr).savedStateSize as usize);
|
||||
let buf: &mut [u8] = std::slice::from_raw_parts_mut(
|
||||
(*app_ptr).savedState.cast(),
|
||||
(*app_ptr).savedStateSize as usize,
|
||||
);
|
||||
let state = buf.to_vec();
|
||||
Some(state)
|
||||
} else {
|
||||
@@ -101,74 +101,96 @@ pub struct AndroidAppWaker {
|
||||
// The looper pointer is owned by the android_app and effectively
|
||||
// has a 'static lifetime, and the ALooper_wake C API is thread
|
||||
// safe, so this can be cloned safely and is send + sync safe
|
||||
looper: NonNull<ALooper>
|
||||
looper: NonNull<ALooper>,
|
||||
}
|
||||
unsafe impl Send for AndroidAppWaker {}
|
||||
unsafe impl Sync for AndroidAppWaker {}
|
||||
|
||||
impl AndroidAppWaker {
|
||||
pub fn wake(&self) {
|
||||
unsafe { ALooper_wake(self.looper.as_ptr()); }
|
||||
unsafe {
|
||||
ALooper_wake(self.looper.as_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AndroidApp {
|
||||
pub(crate) unsafe fn from_ptr(ptr: NonNull<ffi::android_app>) -> Self {
|
||||
|
||||
// Note: we don't use from_ptr since we don't own the android_app.config
|
||||
// and need to keep in mind that the Drop handler is going to call
|
||||
// AConfiguration_delete()
|
||||
//
|
||||
// Whenever we get a ConfigChanged notification we synchronize this
|
||||
// config state with a deep copy.
|
||||
let config = Configuration::clone_from_ptr(NonNull::new_unchecked((*ptr.as_ptr()).config));
|
||||
|
||||
Self {
|
||||
inner: Arc::new(AndroidAppInner {
|
||||
ptr,
|
||||
config: RwLock::new(config),
|
||||
inner: Arc::new(RwLock::new(AndroidAppInner {
|
||||
native_app: NativeAppGlue { ptr },
|
||||
config: ConfigurationRef::new(config),
|
||||
native_window: Default::default(),
|
||||
})
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AndroidAppInner {
|
||||
struct NativeAppGlue {
|
||||
ptr: NonNull<ffi::android_app>,
|
||||
config: RwLock<Configuration>,
|
||||
}
|
||||
impl Deref for NativeAppGlue {
|
||||
type Target = NonNull<ffi::android_app>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.ptr
|
||||
}
|
||||
}
|
||||
unsafe impl Send for NativeAppGlue {}
|
||||
unsafe impl Sync for NativeAppGlue {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AndroidAppInner {
|
||||
native_app: NativeAppGlue,
|
||||
config: ConfigurationRef,
|
||||
native_window: RwLock<Option<NativeWindow>>,
|
||||
}
|
||||
|
||||
impl AndroidAppInner {
|
||||
|
||||
pub fn native_window<'a>(&self) -> Option<NativeWindowRef> {
|
||||
let guard = self.native_window.read().unwrap();
|
||||
if let Some(ref window) = *guard {
|
||||
Some(NativeWindowRef::new(window))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
pub fn native_window<'a>(&self) -> Option<NativeWindow> {
|
||||
self.native_window.read().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn poll_events<F>(&self, timeout: Option<Duration>, mut callback: F)
|
||||
where F: FnMut(PollEvent)
|
||||
where
|
||||
F: FnMut(PollEvent),
|
||||
{
|
||||
trace!("poll_events");
|
||||
|
||||
unsafe {
|
||||
let app_ptr = self.ptr;
|
||||
let native_app = &self.native_app;
|
||||
|
||||
let mut fd: i32 = 0;
|
||||
let mut events: i32 = 0;
|
||||
let mut source: *mut core::ffi::c_void = ptr::null_mut();
|
||||
|
||||
let timeout_milliseconds = if let Some(timeout) = timeout { timeout.as_millis() as i32 } else { -1 };
|
||||
let timeout_milliseconds = if let Some(timeout) = timeout {
|
||||
timeout.as_millis() as i32
|
||||
} else {
|
||||
-1
|
||||
};
|
||||
trace!("Calling ALooper_pollAll, timeout = {timeout_milliseconds}");
|
||||
let id = ALooper_pollAll(timeout_milliseconds, &mut fd, &mut events, &mut source as *mut *mut core::ffi::c_void);
|
||||
let id = ALooper_pollAll(
|
||||
timeout_milliseconds,
|
||||
&mut fd,
|
||||
&mut events,
|
||||
&mut source as *mut *mut core::ffi::c_void,
|
||||
);
|
||||
match id {
|
||||
ffi::ALOOPER_POLL_WAKE => {
|
||||
trace!("ALooper_pollAll returned POLL_WAKE");
|
||||
|
||||
if ffi::android_app_input_available_wake_up(native_app.as_ptr()) {
|
||||
log::debug!("Notifying Input Available");
|
||||
callback(PollEvent::Main(MainEvent::InputAvailable));
|
||||
}
|
||||
|
||||
callback(PollEvent::Wake);
|
||||
}
|
||||
ffi::ALOOPER_POLL_CALLBACK => {
|
||||
@@ -181,14 +203,9 @@ impl AndroidAppInner {
|
||||
callback(PollEvent::Timeout);
|
||||
}
|
||||
ffi::ALOOPER_POLL_ERROR => {
|
||||
trace!("ALooper_pollAll returned POLL_ERROR");
|
||||
callback(PollEvent::Error);
|
||||
|
||||
// Considering that this API is quite likely to be used in `android_main`
|
||||
// it's rather unergonomic to require the call to unwrap a Result for each
|
||||
// call to poll_events(). Alternatively we could maybe even just panic!()
|
||||
// here, while it's hard to imagine practically being able to recover
|
||||
//return Err(LooperError);
|
||||
// If we have an IO error with our pipe to the main Java thread that's surely
|
||||
// not something we can recover from
|
||||
panic!("ALooper_pollAll returned POLL_ERROR");
|
||||
}
|
||||
id if id >= 0 => {
|
||||
match id as u32 {
|
||||
@@ -196,42 +213,74 @@ impl AndroidAppInner {
|
||||
trace!("ALooper_pollAll returned ID_MAIN");
|
||||
let source: *mut ffi::android_poll_source = source.cast();
|
||||
if source != ptr::null_mut() {
|
||||
let cmd_i = ffi::android_app_read_cmd(app_ptr.as_ptr());
|
||||
let cmd_i = ffi::android_app_read_cmd(native_app.as_ptr());
|
||||
|
||||
let cmd = match cmd_i as u32 {
|
||||
//NativeAppGlueAppCmd_UNUSED_APP_CMD_INPUT_CHANGED => AndroidAppMainEvent::InputChanged,
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_INIT_WINDOW => MainEvent::InitWindow {},
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_TERM_WINDOW => MainEvent::TerminateWindow {},
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_WINDOW_RESIZED => MainEvent::WindowResized {},
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_WINDOW_REDRAW_NEEDED => MainEvent::RedrawNeeded {},
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_CONTENT_RECT_CHANGED => MainEvent::ContentRectChanged,
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_GAINED_FOCUS => MainEvent::GainedFocus,
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_LOST_FOCUS => MainEvent::LostFocus,
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_CONFIG_CHANGED => MainEvent::ConfigChanged,
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_LOW_MEMORY => MainEvent::LowMemory,
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_INIT_WINDOW => {
|
||||
MainEvent::InitWindow {}
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_TERM_WINDOW => {
|
||||
MainEvent::TerminateWindow {}
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_WINDOW_RESIZED => {
|
||||
MainEvent::WindowResized {}
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_WINDOW_REDRAW_NEEDED => {
|
||||
MainEvent::RedrawNeeded {}
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_CONTENT_RECT_CHANGED => {
|
||||
MainEvent::ContentRectChanged {}
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_GAINED_FOCUS => {
|
||||
MainEvent::GainedFocus
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_LOST_FOCUS => {
|
||||
MainEvent::LostFocus
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_CONFIG_CHANGED => {
|
||||
MainEvent::ConfigChanged {}
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_LOW_MEMORY => {
|
||||
MainEvent::LowMemory
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_START => MainEvent::Start,
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_RESUME => MainEvent::Resume { loader: StateLoader { app: &self } },
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_SAVE_STATE => MainEvent::SaveState { saver: StateSaver { app: &self } },
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_RESUME => MainEvent::Resume {
|
||||
loader: StateLoader { app: &self },
|
||||
},
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_SAVE_STATE => {
|
||||
MainEvent::SaveState {
|
||||
saver: StateSaver { app: &self },
|
||||
}
|
||||
}
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_PAUSE => MainEvent::Pause,
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_STOP => MainEvent::Stop,
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_DESTROY => MainEvent::Destroy,
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_WINDOW_INSETS_CHANGED => MainEvent::InsetsChanged {},
|
||||
_ => unreachable!()
|
||||
ffi::NativeAppGlueAppCmd_APP_CMD_WINDOW_INSETS_CHANGED => {
|
||||
MainEvent::InsetsChanged {}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
trace!("Read ID_MAIN command {cmd_i} = {cmd:?}");
|
||||
|
||||
trace!("Calling android_app_pre_exec_cmd({cmd_i})");
|
||||
ffi::android_app_pre_exec_cmd(app_ptr.as_ptr(), cmd_i);
|
||||
ffi::android_app_pre_exec_cmd(native_app.as_ptr(), cmd_i);
|
||||
match cmd {
|
||||
MainEvent::ConfigChanged => {
|
||||
*self.config.write().unwrap() =
|
||||
Configuration::clone_from_ptr(NonNull::new_unchecked((*app_ptr.as_ptr()).config));
|
||||
MainEvent::ConfigChanged { .. } => {
|
||||
self.config.replace(Configuration::clone_from_ptr(
|
||||
NonNull::new_unchecked((*native_app.as_ptr()).config),
|
||||
));
|
||||
}
|
||||
MainEvent::InitWindow { .. } => {
|
||||
let win_ptr = (*app_ptr.as_ptr()).window;
|
||||
let win_ptr = (*native_app.as_ptr()).window;
|
||||
// It's important that we use ::clone_from_ptr() here
|
||||
// because NativeWindow has a Drop implementation that
|
||||
// will unconditionally _release() the native window
|
||||
*self.native_window.write().unwrap() =
|
||||
Some(NativeWindow::from_ptr(NonNull::new(win_ptr).unwrap()));
|
||||
Some(NativeWindow::clone_from_ptr(
|
||||
NonNull::new(win_ptr).unwrap(),
|
||||
));
|
||||
}
|
||||
MainEvent::TerminateWindow { .. } => {
|
||||
*self.native_window.write().unwrap() = None;
|
||||
@@ -243,16 +292,13 @@ impl AndroidAppInner {
|
||||
callback(PollEvent::Main(cmd));
|
||||
|
||||
trace!("Calling android_app_post_exec_cmd({cmd_i})");
|
||||
ffi::android_app_post_exec_cmd(app_ptr.as_ptr(), cmd_i);
|
||||
ffi::android_app_post_exec_cmd(native_app.as_ptr(), cmd_i);
|
||||
} else {
|
||||
panic!("ALooper_pollAll returned ID_MAIN event with NULL android_poll_source!");
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let events = FdEvent::from_bits(events as u32)
|
||||
.expect(&format!("Spurious ALooper_pollAll event flags {:#04x}", events as u32));
|
||||
trace!("Custom ALooper event source: id = {id}, fd = {fd}, events = {events:?}, data = {source:?}");
|
||||
callback(PollEvent::FdEvent{ ident: id, fd: fd as RawFd, events, data: source });
|
||||
error!("Ignoring spurious ALooper event source: id = {id}, fd = {fd}, events = {events:?}, data = {source:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -263,34 +309,69 @@ impl AndroidAppInner {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enable_motion_axis(&self, axis: Axis) {
|
||||
pub fn set_window_flags(
|
||||
&self,
|
||||
add_flags: WindowManagerFlags,
|
||||
remove_flags: WindowManagerFlags,
|
||||
) {
|
||||
unsafe {
|
||||
ffi::GameActivityPointerAxes_enableAxis(axis as i32)
|
||||
let activity = (*self.native_app.as_ptr()).activity;
|
||||
ffi::GameActivity_setWindowFlags(activity, add_flags.bits(), remove_flags.bits())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn disable_motion_axis(&self, axis: Axis) {
|
||||
// TODO: move into a trait
|
||||
pub fn show_soft_input(&self, show_implicit: bool) {
|
||||
unsafe {
|
||||
ffi::GameActivityPointerAxes_disableAxis(axis as i32)
|
||||
let activity = (*self.native_app.as_ptr()).activity;
|
||||
let flags = if show_implicit {
|
||||
ffi::ShowImeFlags_SHOW_IMPLICIT
|
||||
} else {
|
||||
0
|
||||
};
|
||||
ffi::GameActivity_showSoftInput(activity, flags);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: move into a trait
|
||||
pub fn hide_soft_input(&self, hide_implicit_only: bool) {
|
||||
unsafe {
|
||||
let activity = (*self.native_app.as_ptr()).activity;
|
||||
let flags = if hide_implicit_only {
|
||||
ffi::HideImeFlags_HIDE_IMPLICIT_ONLY
|
||||
} else {
|
||||
0
|
||||
};
|
||||
ffi::GameActivity_hideSoftInput(activity, flags);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enable_motion_axis(&mut self, axis: Axis) {
|
||||
unsafe { ffi::GameActivityPointerAxes_enableAxis(axis as i32) }
|
||||
}
|
||||
|
||||
pub fn disable_motion_axis(&mut self, axis: Axis) {
|
||||
unsafe { ffi::GameActivityPointerAxes_disableAxis(axis as i32) }
|
||||
}
|
||||
|
||||
pub fn create_waker(&self) -> AndroidAppWaker {
|
||||
unsafe {
|
||||
// From the application's pov we assume the app_ptr and looper pointer
|
||||
// have static lifetimes and we can safely assume they are never NULL.
|
||||
let app_ptr = self.ptr.as_ptr();
|
||||
AndroidAppWaker { looper: NonNull::new_unchecked((*app_ptr).looper) }
|
||||
let app_ptr = self.native_app.as_ptr();
|
||||
AndroidAppWaker {
|
||||
looper: NonNull::new_unchecked((*app_ptr).looper),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn config(&self) -> Configuration {
|
||||
self.config.read().unwrap().clone()
|
||||
pub fn config(&self) -> ConfigurationRef {
|
||||
self.config.clone()
|
||||
}
|
||||
|
||||
pub fn content_rect(&self) -> Rect {
|
||||
unsafe {
|
||||
let app_ptr = self.ptr.as_ptr();
|
||||
let app_ptr = self.native_app.as_ptr();
|
||||
Rect {
|
||||
left: (*app_ptr).contentRect.left,
|
||||
right: (*app_ptr).contentRect.right,
|
||||
@@ -302,17 +383,18 @@ impl AndroidAppInner {
|
||||
|
||||
pub fn asset_manager(&self) -> AssetManager {
|
||||
unsafe {
|
||||
let app_ptr = self.ptr.as_ptr();
|
||||
let app_ptr = self.native_app.as_ptr();
|
||||
let am_ptr = NonNull::new_unchecked((*(*app_ptr).activity).assetManager);
|
||||
AssetManager::from_ptr(am_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn input_events<'b, F>(&self, mut callback: F)
|
||||
where F: FnMut(&InputEvent)
|
||||
where
|
||||
F: FnMut(&InputEvent),
|
||||
{
|
||||
let buf = unsafe {
|
||||
let app_ptr = self.ptr.as_ptr();
|
||||
let app_ptr = self.native_app.as_ptr();
|
||||
let input_buffer = ffi::android_app_swap_input_buffers(app_ptr);
|
||||
if input_buffer == ptr::null_mut() {
|
||||
return;
|
||||
@@ -328,34 +410,24 @@ impl AndroidAppInner {
|
||||
}
|
||||
}
|
||||
|
||||
fn try_get_path_from_ptr(path: *const u8) -> Option<std::path::PathBuf> {
|
||||
if path == ptr::null() { return None; }
|
||||
let cstr = unsafe {
|
||||
let cstr_slice = CStr::from_ptr(path);
|
||||
cstr_slice.to_str().ok()?
|
||||
};
|
||||
if cstr.len() == 0 { return None; }
|
||||
Some(std::path::PathBuf::from(cstr))
|
||||
}
|
||||
|
||||
pub fn internal_data_path(&self) -> Option<std::path::PathBuf> {
|
||||
unsafe {
|
||||
let app_ptr = self.ptr.as_ptr();
|
||||
Self::try_get_path_from_ptr((*(*app_ptr).activity).internalDataPath)
|
||||
let app_ptr = self.native_app.as_ptr();
|
||||
util::try_get_path_from_ptr((*(*app_ptr).activity).internalDataPath)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn external_data_path(&self) -> Option<std::path::PathBuf> {
|
||||
unsafe {
|
||||
let app_ptr = self.ptr.as_ptr();
|
||||
Self::try_get_path_from_ptr((*(*app_ptr).activity).externalDataPath)
|
||||
let app_ptr = self.native_app.as_ptr();
|
||||
util::try_get_path_from_ptr((*(*app_ptr).activity).externalDataPath)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn obb_path(&self) -> Option<std::path::PathBuf> {
|
||||
unsafe {
|
||||
let app_ptr = self.ptr.as_ptr();
|
||||
Self::try_get_path_from_ptr((*(*app_ptr).activity).obbPath)
|
||||
let app_ptr = self.native_app.as_ptr();
|
||||
util::try_get_path_from_ptr((*(*app_ptr).activity).obbPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -363,7 +435,7 @@ impl AndroidAppInner {
|
||||
struct MotionEventsIterator<'a> {
|
||||
pos: usize,
|
||||
count: usize,
|
||||
buffer: &'a InputBuffer<'a>
|
||||
buffer: &'a InputBuffer<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for MotionEventsIterator<'a> {
|
||||
@@ -386,7 +458,7 @@ impl<'a> Iterator for MotionEventsIterator<'a> {
|
||||
struct KeyEventsIterator<'a> {
|
||||
pos: usize,
|
||||
count: usize,
|
||||
buffer: &'a InputBuffer<'a>
|
||||
buffer: &'a InputBuffer<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for KeyEventsIterator<'a> {
|
||||
@@ -408,14 +480,14 @@ impl<'a> Iterator for KeyEventsIterator<'a> {
|
||||
|
||||
struct InputBuffer<'a> {
|
||||
ptr: NonNull<ffi::android_input_buffer>,
|
||||
_lifetime: PhantomData<&'a ffi::android_input_buffer>
|
||||
_lifetime: PhantomData<&'a ffi::android_input_buffer>,
|
||||
}
|
||||
|
||||
impl<'a> InputBuffer<'a> {
|
||||
pub(crate) fn from_ptr(ptr: NonNull<ffi::android_input_buffer>) -> InputBuffer<'a> {
|
||||
Self {
|
||||
ptr,
|
||||
_lifetime: PhantomData::default()
|
||||
_lifetime: PhantomData::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,14 +497,22 @@ impl<'a> InputBuffer<'a> {
|
||||
pub fn motion_events_iter<'b>(&'b self) -> MotionEventsIterator<'b> {
|
||||
unsafe {
|
||||
let count = (*self.ptr.as_ptr()).motionEventsCount as usize;
|
||||
MotionEventsIterator { pos: 0, count, buffer: self }
|
||||
MotionEventsIterator {
|
||||
pos: 0,
|
||||
count,
|
||||
buffer: self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn key_events_iter<'b>(&'b self) -> KeyEventsIterator<'b> {
|
||||
unsafe {
|
||||
let count = (*self.ptr.as_ptr()).keyEventsCount as usize;
|
||||
KeyEventsIterator { pos: 0, count, buffer: self }
|
||||
KeyEventsIterator {
|
||||
pos: 0,
|
||||
count,
|
||||
buffer: self,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -473,41 +553,48 @@ extern "C" {
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Java_com_google_androidgamesdk_GameActivity_loadNativeCode(
|
||||
env: *mut JNIEnv,
|
||||
java_game_activity: jobject,
|
||||
path: jstring,
|
||||
func_name: jstring,
|
||||
internal_data_dir: jstring,
|
||||
obb_dir: jstring,
|
||||
external_data_dir: jstring,
|
||||
jasset_mgr: jobject,
|
||||
saved_state: jbyteArray,
|
||||
) -> jni_sys::jlong
|
||||
{
|
||||
Java_com_google_androidgamesdk_GameActivity_loadNativeCode_C(env, java_game_activity, path, func_name,
|
||||
internal_data_dir, obb_dir, external_data_dir, jasset_mgr, saved_state)
|
||||
env: *mut JNIEnv,
|
||||
java_game_activity: jobject,
|
||||
path: jstring,
|
||||
func_name: jstring,
|
||||
internal_data_dir: jstring,
|
||||
obb_dir: jstring,
|
||||
external_data_dir: jstring,
|
||||
jasset_mgr: jobject,
|
||||
saved_state: jbyteArray,
|
||||
) -> jni_sys::jlong {
|
||||
Java_com_google_androidgamesdk_GameActivity_loadNativeCode_C(
|
||||
env,
|
||||
java_game_activity,
|
||||
path,
|
||||
func_name,
|
||||
internal_data_dir,
|
||||
obb_dir,
|
||||
external_data_dir,
|
||||
jasset_mgr,
|
||||
saved_state,
|
||||
)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn GameActivity_onCreate(
|
||||
activity: *mut ffi::GameActivity,
|
||||
saved_state: *mut ::std::os::raw::c_void,
|
||||
saved_state_size: ffi::size_t,
|
||||
)
|
||||
{
|
||||
activity: *mut ffi::GameActivity,
|
||||
saved_state: *mut ::std::os::raw::c_void,
|
||||
saved_state_size: ffi::size_t,
|
||||
) {
|
||||
GameActivity_onCreate_C(activity, saved_state, saved_state_size);
|
||||
}
|
||||
|
||||
fn android_log(level: Level, tag: &CStr, msg: &CStr) {
|
||||
let prio = match level {
|
||||
Level::Error => ndk_sys::android_LogPriority_ANDROID_LOG_ERROR,
|
||||
Level::Warn => ndk_sys::android_LogPriority_ANDROID_LOG_WARN,
|
||||
Level::Info => ndk_sys::android_LogPriority_ANDROID_LOG_INFO,
|
||||
Level::Debug => ndk_sys::android_LogPriority_ANDROID_LOG_DEBUG,
|
||||
Level::Trace => ndk_sys::android_LogPriority_ANDROID_LOG_VERBOSE,
|
||||
Level::Error => ndk_sys::android_LogPriority::ANDROID_LOG_ERROR,
|
||||
Level::Warn => ndk_sys::android_LogPriority::ANDROID_LOG_WARN,
|
||||
Level::Info => ndk_sys::android_LogPriority::ANDROID_LOG_INFO,
|
||||
Level::Debug => ndk_sys::android_LogPriority::ANDROID_LOG_DEBUG,
|
||||
Level::Trace => ndk_sys::android_LogPriority::ANDROID_LOG_VERBOSE,
|
||||
};
|
||||
unsafe {
|
||||
ndk_sys::__android_log_write(prio as raw::c_int, tag.as_ptr(), msg.as_ptr());
|
||||
ndk_sys::__android_log_write(prio.0 as raw::c_int, tag.as_ptr(), msg.as_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,7 +607,6 @@ extern "Rust" {
|
||||
// by android_native_app_glue.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn _rust_glue_entry(app: *mut ffi::android_app) {
|
||||
|
||||
// Maybe make this stdout/stderr redirection an optional / opt-in feature?...
|
||||
let mut logpipe: [RawFd; 2] = Default::default();
|
||||
libc::pipe(logpipe.as_mut_ptr());
|
||||
@@ -575,4 +661,4 @@ pub unsafe extern "C" fn _rust_glue_entry(app: *mut ffi::android_app) {
|
||||
}
|
||||
|
||||
ndk_context::release_android_context();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,59 @@
|
||||
use std::time::Duration;
|
||||
use std::{os::unix::prelude::RawFd, sync::Arc};
|
||||
use std::hash::Hash;
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
use std::sync::RwLock;
|
||||
use std::time::Duration;
|
||||
|
||||
use ndk::asset::AssetManager;
|
||||
use ndk::configuration::Configuration;
|
||||
// TODO: import FdEvent and avoid depending on ndk Looper abstraction in case we want to
|
||||
// support using epoll directly in the future.
|
||||
use ndk::looper::FdEvent;
|
||||
use ndk::native_window::NativeWindow;
|
||||
|
||||
use bitflags::bitflags;
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
compile_error!("android-activity only supports compiling for Android");
|
||||
|
||||
#[cfg(all(feature = "game-activity", feature = "native-activity"))]
|
||||
compile_error!("The \"game-activity\" and \"native-activity\" features cannot be enabled at the same time");
|
||||
#[cfg(not(any(feature = "game-activity", feature = "native-activity")))]
|
||||
compile_error!("Either \"game-activity\" or \"native-activity\" must be enabled as features");
|
||||
compile_error!(
|
||||
"The \"game-activity\" and \"native-activity\" features cannot be enabled at the same time"
|
||||
);
|
||||
#[cfg(all(
|
||||
not(any(feature = "game-activity", feature = "native-activity")),
|
||||
not(doc)
|
||||
))]
|
||||
compile_error!(
|
||||
r#"Either \"game-activity\" or \"native-activity\" must be enabled as features
|
||||
|
||||
If you have set one of these features then this error indicates that Cargo is trying to
|
||||
link together multiple implementations of android-activity (with incompatible versions)
|
||||
which is not supported.
|
||||
|
||||
#[cfg(feature="native-activity")]
|
||||
Since android-activity is responsible for the `android_main` entrypoint of your application
|
||||
then there can only be a single implementation of android-activity linked with your application.
|
||||
|
||||
You can use `cargo tree` (e.g. via `cargo ndk -t arm64-v8a tree`) to identify why multiple
|
||||
versions have been resolved.
|
||||
|
||||
You may need to add a `[patch]` into your Cargo.toml to ensure a specific version of
|
||||
android-activity is used across all of your application's crates.
|
||||
"#
|
||||
);
|
||||
|
||||
#[cfg(any(feature = "native-activity", doc))]
|
||||
mod native_activity;
|
||||
#[cfg(feature="native-activity")]
|
||||
#[cfg(any(feature = "native-activity", doc))]
|
||||
use native_activity as activity_impl;
|
||||
|
||||
#[cfg(feature="game-activity")]
|
||||
#[cfg(feature = "game-activity")]
|
||||
mod game_activity;
|
||||
#[cfg(feature="game-activity")]
|
||||
#[cfg(feature = "game-activity")]
|
||||
use game_activity as activity_impl;
|
||||
|
||||
pub use activity_impl::input;
|
||||
|
||||
mod config;
|
||||
pub use config::ConfigurationRef;
|
||||
|
||||
mod util;
|
||||
|
||||
// Note: unlike in ndk-glue this has signed components (consistent
|
||||
// with Android's ARect) which generally allows for representing
|
||||
// rectangles with a negative/off-screen origin. Even though this
|
||||
@@ -46,56 +69,31 @@ pub struct Rect {
|
||||
pub bottom: i32,
|
||||
}
|
||||
|
||||
// XXX: NativeWindow is a ref-counted object but the NativeWindow rust API
|
||||
// doesn't currently implement Clone() in terms of acquiring a reference
|
||||
// and Drop() in terms of releasing a reference. NativeWindowRef lets
|
||||
// us expose a pointer to a NativeWindow more safely by ensuring it won't
|
||||
// become invalid, even it it gets 'terminated'.
|
||||
|
||||
/// A reference to a `NativeWindow`, used for rendering
|
||||
pub struct NativeWindowRef {
|
||||
inner: NativeWindow
|
||||
}
|
||||
impl NativeWindowRef {
|
||||
pub fn new(native_window: &NativeWindow) -> Self {
|
||||
unsafe { ndk_sys::ANativeWindow_acquire(native_window.ptr().as_ptr()); }
|
||||
Self { inner: native_window.clone() }
|
||||
}
|
||||
}
|
||||
impl Drop for NativeWindowRef {
|
||||
fn drop(&mut self) {
|
||||
unsafe { ndk_sys::ANativeWindow_release(self.inner.ptr().as_ptr()) }
|
||||
}
|
||||
}
|
||||
impl Deref for NativeWindowRef {
|
||||
type Target = NativeWindow;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
pub type StateSaver<'a> = activity_impl::StateSaver<'a>;
|
||||
pub type StateLoader<'a> = activity_impl::StateLoader<'a>;
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug)]
|
||||
pub enum MainEvent<'a> {
|
||||
/**
|
||||
* Unused. Reserved for future use when usage of AInputQueue will be
|
||||
* supported.
|
||||
*/
|
||||
//InputChanged,
|
||||
/// New input events are available via [`AndroidApp::input_events()`]
|
||||
///
|
||||
/// _Note: Even if more input is received this event will not be resent
|
||||
/// until [`AndroidApp::input_events()`] has been called, which enables
|
||||
/// applications to batch up input processing without there being lots of
|
||||
/// redundant event loop wake ups._
|
||||
///
|
||||
/// [`AndroidApp::input_events()`]: AndroidApp::input_events
|
||||
InputAvailable,
|
||||
|
||||
/// Command from main thread: a new [`NativeWindow`] is ready for use. Upon
|
||||
/// receiving this command, [`native_window()`] will return the new window
|
||||
/// receiving this command, [`AndroidApp::native_window()`] will return the new window
|
||||
#[non_exhaustive]
|
||||
InitWindow { },
|
||||
InitWindow {},
|
||||
|
||||
/// Command from main thread: the existing [`NativeWindow`] needs to be
|
||||
/// terminated. Upon receiving this command, [`native_window()`] still
|
||||
/// terminated. Upon receiving this command, [`AndroidApp::native_window()`] still
|
||||
/// returns the existing window; after returning from the [`AndroidApp::poll_events()`]
|
||||
/// callback then [`native_window()`] will return `None`.
|
||||
/// callback then [`AndroidApp::native_window()`] will return `None`.
|
||||
#[non_exhaustive]
|
||||
TerminateWindow {},
|
||||
|
||||
@@ -114,7 +112,8 @@ pub enum MainEvent<'a> {
|
||||
/// Command from main thread: the content area of the window has changed,
|
||||
/// such as from the soft input window being shown or hidden. You can
|
||||
/// get the new content rect by calling [`AndroidApp::content_rect()`]
|
||||
ContentRectChanged,
|
||||
#[non_exhaustive]
|
||||
ContentRectChanged {},
|
||||
|
||||
/// Command from main thread: the app's activity window has gained
|
||||
/// input focus.
|
||||
@@ -125,9 +124,10 @@ pub enum MainEvent<'a> {
|
||||
LostFocus,
|
||||
|
||||
/// Command from main thread: the current device configuration has changed.
|
||||
/// You can get a copy of the latest [Configuration] by calling
|
||||
/// You can get a copy of the latest [`ndk::configuration::Configuration`] by calling
|
||||
/// [`AndroidApp::config()`]
|
||||
ConfigChanged,
|
||||
#[non_exhaustive]
|
||||
ConfigChanged {},
|
||||
|
||||
/// Command from main thread: the system is running low on memory.
|
||||
/// Try to reduce your memory use.
|
||||
@@ -169,20 +169,180 @@ pub enum PollEvent<'a> {
|
||||
Wake,
|
||||
Timeout,
|
||||
Main(MainEvent<'a>),
|
||||
|
||||
#[non_exhaustive]
|
||||
FdEvent { ident: i32, fd: RawFd, events: FdEvent, data: *mut std::ffi::c_void },
|
||||
|
||||
Error
|
||||
}
|
||||
|
||||
use activity_impl::AndroidAppInner;
|
||||
|
||||
pub use activity_impl::AndroidAppWaker;
|
||||
|
||||
bitflags! {
|
||||
/// Flags for [`AndroidApp::set_window_flags`]
|
||||
/// as per the [android.view.WindowManager.LayoutParams Java API](https://developer.android.com/reference/android/view/WindowManager.LayoutParams)
|
||||
pub struct WindowManagerFlags: u32 {
|
||||
/// As long as this window is visible to the user, allow the lock
|
||||
/// screen to activate while the screen is on. This can be used
|
||||
/// independently, or in combination with
|
||||
/// [`Self::KEEP_SCREEN_ON`] and/or [`Self::SHOW_WHEN_LOCKED`]
|
||||
const ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001;
|
||||
|
||||
/// Everything behind this window will be dimmed. */
|
||||
const DIM_BEHIND = 0x00000002;
|
||||
|
||||
/// Blur everything behind this window.
|
||||
#[deprecated = "Blurring is no longer supported"]
|
||||
const BLUR_BEHIND = 0x00000004;
|
||||
|
||||
/// This window won't ever get key input focus, so the
|
||||
/// user can not send key or other button events to it. Those will
|
||||
/// instead go to whatever focusable window is behind it. This flag
|
||||
/// will also enable [`Self::NOT_TOUCH_MODAL`] whether or not
|
||||
/// that is explicitly set.
|
||||
///
|
||||
/// Setting this flag also implies that the window will not need to
|
||||
/// interact with
|
||||
/// a soft input method, so it will be Z-ordered and positioned
|
||||
/// independently of any active input method (typically this means it
|
||||
/// gets Z-ordered on top of the input method, so it can use the full
|
||||
/// screen for its content and cover the input method if needed. You
|
||||
/// can use [`Self::ALT_FOCUSABLE_IM`] to modify this
|
||||
/// behavior.
|
||||
const NOT_FOCUSABLE = 0x00000008;
|
||||
|
||||
/// This window can never receive touch events.
|
||||
const NOT_TOUCHABLE = 0x00000010;
|
||||
|
||||
/// Even when this window is focusable (if
|
||||
/// [`Self::NOT_FOCUSABLE`] is not set), allow any pointer
|
||||
/// events outside of the window to be sent to the windows behind it.
|
||||
/// Otherwise it will consume all pointer events itself, regardless of
|
||||
/// whether they are inside of the window.
|
||||
const NOT_TOUCH_MODAL = 0x00000020;
|
||||
|
||||
/// When set, if the device is asleep when the touch
|
||||
/// screen is pressed, you will receive this first touch event. Usually
|
||||
/// the first touch event is consumed by the system since the user can
|
||||
/// not see what they are pressing on.
|
||||
#[deprecated]
|
||||
const TOUCHABLE_WHEN_WAKING = 0x00000040;
|
||||
|
||||
/// As long as this window is visible to the user, keep
|
||||
/// the device's screen turned on and bright.
|
||||
const KEEP_SCREEN_ON = 0x00000080;
|
||||
|
||||
/// Place the window within the entire screen, ignoring
|
||||
/// decorations around the border (such as the status bar). The
|
||||
/// window must correctly position its contents to take the screen
|
||||
/// decoration into account.
|
||||
const LAYOUT_IN_SCREEN = 0x00000100;
|
||||
|
||||
/// Allows the window to extend outside of the screen.
|
||||
const LAYOUT_NO_LIMITS = 0x00000200;
|
||||
|
||||
/// Hide all screen decorations (such as the status
|
||||
/// bar) while this window is displayed. This allows the window to
|
||||
/// use the entire display space for itself -- the status bar will
|
||||
/// be hidden when an app window with this flag set is on the top
|
||||
/// layer. A fullscreen window will ignore a value of
|
||||
/// [`Self::SOFT_INPUT_ADJUST_RESIZE`] the window will stay
|
||||
/// fullscreen and will not resize.
|
||||
const FULLSCREEN = 0x00000400;
|
||||
|
||||
/// Override [`Self::FULLSCREEN`] and force the
|
||||
/// screen decorations (such as the status bar) to be shown.
|
||||
const FORCE_NOT_FULLSCREEN = 0x00000800;
|
||||
/// Turn on dithering when compositing this window to
|
||||
/// the screen.
|
||||
#[deprecated="This flag is no longer used"]
|
||||
const DITHER = 0x00001000;
|
||||
|
||||
/// Treat the content of the window as secure, preventing
|
||||
/// it from appearing in screenshots or from being viewed on non-secure
|
||||
/// displays.
|
||||
const SECURE = 0x00002000;
|
||||
|
||||
/// A special mode where the layout parameters are used
|
||||
/// to perform scaling of the surface when it is composited to the
|
||||
/// screen.
|
||||
const SCALED = 0x00004000;
|
||||
|
||||
/// Intended for windows that will often be used when the user is
|
||||
/// holding the screen against their face, it will aggressively
|
||||
/// filter the event stream to prevent unintended presses in this
|
||||
/// situation that may not be desired for a particular window, when
|
||||
/// such an event stream is detected, the application will receive
|
||||
/// a `AMOTION_EVENT_ACTION_CANCEL` to indicate this so
|
||||
/// applications can handle this accordingly by taking no action on
|
||||
/// the event until the finger is released.
|
||||
const IGNORE_CHEEK_PRESSES = 0x00008000;
|
||||
|
||||
/// A special option only for use in combination with
|
||||
/// [`Self::LAYOUT_IN_SCREEN`]. When requesting layout in
|
||||
/// the screen your window may appear on top of or behind screen decorations
|
||||
/// such as the status bar. By also including this flag, the window
|
||||
/// manager will report the inset rectangle needed to ensure your
|
||||
/// content is not covered by screen decorations.
|
||||
const LAYOUT_INSET_DECOR = 0x00010000;
|
||||
|
||||
/// Invert the state of [`Self::NOT_FOCUSABLE`] with
|
||||
/// respect to how this window interacts with the current method.
|
||||
/// That is, if [`Self::NOT_FOCUSABLE`] is set and this flag is set,
|
||||
/// then the window will behave as if it needs to interact with the
|
||||
/// input method and thus be placed behind/away from it; if
|
||||
/// [`Self::NOT_FOCUSABLE`] is not set and this flag is set,
|
||||
/// then the window will behave as if it doesn't need to interact
|
||||
/// with the input method and can be placed to use more space and
|
||||
/// cover the input method.
|
||||
const ALT_FOCUSABLE_IM = 0x00020000;
|
||||
|
||||
/// If you have set [`Self::NOT_TOUCH_MODAL`], you
|
||||
/// can set this flag to receive a single special MotionEvent with
|
||||
/// the action
|
||||
/// `AMOTION_EVENT_ACTION_OUTSIDE` for
|
||||
/// touches that occur outside of your window. Note that you will not
|
||||
/// receive the full down/move/up gesture, only the location of the
|
||||
/// first down as an `AMOTION_EVENT_ACTION_OUTSIDE`.
|
||||
const WATCH_OUTSIDE_TOUCH = 0x00040000;
|
||||
|
||||
/// Special flag to let windows be shown when the screen
|
||||
/// is locked. This will let application windows take precedence over
|
||||
/// key guard or any other lock screens. Can be used with
|
||||
/// [`Self::KEEP_SCREEN_ON`] to turn screen on and display
|
||||
/// windows directly before showing the key guard window. Can be used with
|
||||
/// [`Self::DISMISS_KEYGUARD`] to automatically fully
|
||||
/// dismiss non-secure key guards. This flag only applies to the top-most
|
||||
/// full-screen window.
|
||||
const SHOW_WHEN_LOCKED = 0x00080000;
|
||||
|
||||
/// Ask that the system wallpaper be shown behind
|
||||
/// your window. The window surface must be translucent to be able
|
||||
/// to actually see the wallpaper behind it; this flag just ensures
|
||||
/// that the wallpaper surface will be there if this window actually
|
||||
/// has translucent regions.
|
||||
const SHOW_WALLPAPER = 0x00100000;
|
||||
|
||||
/// When set as a window is being added or made
|
||||
/// visible, once the window has been shown then the system will
|
||||
/// poke the power manager's user activity (as if the user had woken
|
||||
/// up the device) to turn the screen on.
|
||||
const TURN_SCREEN_ON = 0x00200000;
|
||||
|
||||
/// When set the window will cause the key guard to
|
||||
/// be dismissed, only if it is not a secure lock key guard. Because such
|
||||
/// a key guard is not needed for security, it will never re-appear if
|
||||
/// the user navigates to another window (in contrast to
|
||||
/// [`Self::SHOW_WHEN_LOCKED`], which will only temporarily
|
||||
/// hide both secure and non-secure key guards but ensure they reappear
|
||||
/// when the user moves to another UI that doesn't hide them).
|
||||
/// If the key guard is currently active and is secure (requires an
|
||||
/// unlock pattern) then the user will still need to confirm it before
|
||||
/// seeing this window, unless [`Self::SHOW_WHEN_LOCKED`] has
|
||||
/// also been set.
|
||||
const DISMISS_KEYGUARD = 0x00400000;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AndroidApp {
|
||||
pub(crate) inner: Arc<AndroidAppInner>
|
||||
pub(crate) inner: Arc<RwLock<AndroidAppInner>>,
|
||||
}
|
||||
|
||||
impl PartialEq for AndroidApp {
|
||||
@@ -202,20 +362,20 @@ impl AndroidApp {
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "native-activity")))]
|
||||
#[cfg(feature = "native-activity")]
|
||||
pub(crate) fn native_activity(&self) -> *const ndk_sys::ANativeActivity {
|
||||
self.inner.native_activity()
|
||||
self.inner.read().unwrap().native_activity()
|
||||
}
|
||||
|
||||
/// Queries the current [`NativeWindow`] for the application.
|
||||
///
|
||||
/// This will only return `Some(window)` between
|
||||
/// [`AndroidAppMainEvent::InitWindow`] and [`AndroidAppMainEvent::TerminateWindow`]
|
||||
/// [`MainEvent::InitWindow`] and [`MainEvent::TerminateWindow`]
|
||||
/// events.
|
||||
pub fn native_window<'a>(&self) -> Option<NativeWindowRef> {
|
||||
self.inner.native_window()
|
||||
pub fn native_window<'a>(&self) -> Option<NativeWindow> {
|
||||
self.inner.read().unwrap().native_window()
|
||||
}
|
||||
|
||||
/// Calls [`ALooper_pollAll`] on the looper associated with this AndroidApp as well
|
||||
/// as processing any events (such as lifecycle events) via the given `callback`.
|
||||
/// Polls for any events associated with this AndroidApp and processes those events
|
||||
/// (such as lifecycle events) via the given `callback`.
|
||||
///
|
||||
/// It's important to use this API for polling, and not call [`ALooper_pollAll`] directly since
|
||||
/// some events require pre- and post-processing either side of the callback. For correct
|
||||
@@ -226,62 +386,105 @@ impl AndroidApp {
|
||||
/// main thread. The [`MainEvent::SaveState`] event is also synchronized with the
|
||||
/// Java main thread.
|
||||
///
|
||||
/// # Safety
|
||||
/// This API must only be called from the application's main thread
|
||||
/// [`ALooper_pollAll`]: ndk::looper::ThreadLooper::poll_all
|
||||
pub fn poll_events<F>(&self, timeout: Option<Duration>, callback: F)
|
||||
where F: FnMut(PollEvent)
|
||||
where
|
||||
F: FnMut(PollEvent),
|
||||
{
|
||||
self.inner.poll_events(timeout, callback);
|
||||
self.inner.read().unwrap().poll_events(timeout, callback);
|
||||
}
|
||||
|
||||
/// Creates a means to wake up the main loop while it is blocked waiting for
|
||||
/// events within [`poll_events()`].
|
||||
///
|
||||
/// Internally this uses [`ALooper_wake`] on the looper associated with this
|
||||
/// [AndroidApp].
|
||||
///
|
||||
/// # Safety
|
||||
/// This API can be used from any thread
|
||||
/// events within [`AndroidApp::poll_events()`].
|
||||
pub fn create_waker(&self) -> activity_impl::AndroidAppWaker {
|
||||
self.inner.create_waker()
|
||||
self.inner.read().unwrap().create_waker()
|
||||
}
|
||||
|
||||
/// Returns a deep copy of this application's [`Configuration`]
|
||||
pub fn config(&self) -> Configuration {
|
||||
self.inner.config()
|
||||
/// Returns a (cheaply clonable) reference to this application's [`ndk::configuration::Configuration`]
|
||||
pub fn config(&self) -> ConfigurationRef {
|
||||
self.inner.read().unwrap().config()
|
||||
}
|
||||
|
||||
/// Queries the current content rectangle of the window; this is the area where the
|
||||
/// window's content should be placed to be seen by the user.
|
||||
///
|
||||
/// # Safety
|
||||
/// This API must only be called from the applications main thread
|
||||
pub fn content_rect(&self) -> Rect {
|
||||
self.inner.content_rect()
|
||||
self.inner.read().unwrap().content_rect()
|
||||
}
|
||||
|
||||
/// Queries the Asset Manager instance for the application.
|
||||
///
|
||||
/// Use this to access binary assets bundled inside your application's .apk file.
|
||||
///
|
||||
/// # Safety
|
||||
/// This API must only be called from the applications main thread
|
||||
pub fn asset_manager(&self) -> AssetManager {
|
||||
self.inner.asset_manager()
|
||||
self.inner.read().unwrap().asset_manager()
|
||||
}
|
||||
|
||||
/// Change the window flags of the given activity.
|
||||
///
|
||||
/// Note that some flags must be set before the window decoration is created,
|
||||
/// see
|
||||
/// `<https://developer.android.com/reference/android/view/Window#setFlags(int,%20int)>`.
|
||||
pub fn set_window_flags(
|
||||
&self,
|
||||
add_flags: WindowManagerFlags,
|
||||
remove_flags: WindowManagerFlags,
|
||||
) {
|
||||
self.inner
|
||||
.write()
|
||||
.unwrap()
|
||||
.set_window_flags(add_flags, remove_flags);
|
||||
}
|
||||
|
||||
/// Enable additional input axis
|
||||
///
|
||||
/// To reduce overhead, by default only [`input::Axis::X`] and [`input::Axis::Y`] are enabled
|
||||
/// and other axis should be enabled explicitly.
|
||||
pub fn enable_motion_axis(&self, axis: input::Axis) {
|
||||
self.inner.enable_motion_axis(axis);
|
||||
self.inner.write().unwrap().enable_motion_axis(axis);
|
||||
}
|
||||
|
||||
/// Disable input axis
|
||||
///
|
||||
/// To reduce overhead, by default only [`input::Axis::X`] and [`input::Axis::Y`] are enabled
|
||||
/// and other axis should be enabled explicitly.
|
||||
pub fn disable_motion_axis(&self, axis: input::Axis) {
|
||||
self.inner.disable_motion_axis(axis);
|
||||
self.inner.write().unwrap().disable_motion_axis(axis);
|
||||
}
|
||||
|
||||
/// Explicitly request that the current input method's soft input area be
|
||||
/// shown to the user, if needed.
|
||||
///
|
||||
/// Call this if the user interacts with your view in such a way that they
|
||||
/// have expressed they would like to start performing input into it.
|
||||
pub fn show_soft_input(&self, show_implicit: bool) {
|
||||
self.inner.read().unwrap().show_soft_input(show_implicit);
|
||||
}
|
||||
|
||||
/// Request to hide the soft input window from the context of the window
|
||||
/// that is currently accepting input.
|
||||
///
|
||||
/// This should be called as a result of the user doing some action that
|
||||
/// fairly explicitly requests to have the input window hidden.
|
||||
pub fn hide_soft_input(&self, hide_implicit_only: bool) {
|
||||
self.inner
|
||||
.read()
|
||||
.unwrap()
|
||||
.hide_soft_input(hide_implicit_only);
|
||||
}
|
||||
|
||||
/// Query and process all out-standing input event
|
||||
///
|
||||
/// Applications are generally either expected to call this in-sync with their rendering or
|
||||
/// in response to a [`MainEvent::InputAvailable`] event being delivered. _Note though that your
|
||||
/// application is will only be delivered a single [`MainEvent::InputAvailable`] event between calls
|
||||
/// to this API._
|
||||
///
|
||||
/// To reduce overhead, by default only [`input::Axis::X`] and [`input::Axis::Y`] are enabled
|
||||
/// and other axis should be enabled explicitly via [`Self::enable_motion_axis`].
|
||||
pub fn input_events<'b, F>(&self, callback: F)
|
||||
where F: FnMut(&input::InputEvent)
|
||||
where
|
||||
F: FnMut(&input::InputEvent),
|
||||
{
|
||||
self.inner.input_events(callback);
|
||||
self.inner.read().unwrap().input_events(callback);
|
||||
}
|
||||
|
||||
/// The user-visible SDK version of the framework
|
||||
@@ -298,16 +501,22 @@ impl AndroidApp {
|
||||
|
||||
/// Path to this application's internal data directory
|
||||
pub fn internal_data_path(&self) -> Option<std::path::PathBuf> {
|
||||
self.inner.internal_data_path()
|
||||
self.inner.read().unwrap().internal_data_path()
|
||||
}
|
||||
|
||||
/// Path to this application's external data directory
|
||||
pub fn external_data_path(&self) -> Option<std::path::PathBuf> {
|
||||
self.inner.external_data_path()
|
||||
self.inner.read().unwrap().external_data_path()
|
||||
}
|
||||
|
||||
/// Path to the directory containing the application's OBB files (if any).
|
||||
pub fn obb_path(&self) -> Option<std::path::PathBuf> {
|
||||
self.inner.obb_path()
|
||||
self.inner.read().unwrap().obb_path()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_app_is_send_sync() {
|
||||
fn needs_send_sync<T: Send + Sync>() {}
|
||||
needs_send_sync::<AndroidApp>();
|
||||
}
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
use jni_sys::*;
|
||||
use ndk_sys::AAssetManager;
|
||||
use ndk_sys::ANativeWindow;
|
||||
use ndk_sys::{ALooper, AConfiguration, AInputQueue};
|
||||
|
||||
use ndk_sys::{AConfiguration, AInputQueue, ALooper};
|
||||
|
||||
#[cfg(all(
|
||||
any(target_os = "android", feature = "test"),
|
||||
@@ -31,4 +30,4 @@ include!("ffi_aarch64.rs");
|
||||
include!("ffi_i686.rs");
|
||||
|
||||
#[cfg(all(any(target_os = "android", feature = "test"), target_arch = "x86_64"))]
|
||||
include!("ffi_x86_64.rs");
|
||||
include!("ffi_x86_64.rs");
|
||||
|
||||
@@ -21,10 +21,13 @@ pub const __ANDROID_API_O_MR1__: u32 = 27;
|
||||
pub const __ANDROID_API_P__: u32 = 28;
|
||||
pub const __ANDROID_API_Q__: u32 = 29;
|
||||
pub const __ANDROID_API_R__: u32 = 30;
|
||||
pub const __NDK_MAJOR__: u32 = 21;
|
||||
pub const __NDK_MINOR__: u32 = 1;
|
||||
pub const __ANDROID_API_S__: u32 = 31;
|
||||
pub const __ANDROID_API_T__: u32 = 33;
|
||||
pub const __ANDROID_NDK__: u32 = 1;
|
||||
pub const __NDK_MAJOR__: u32 = 25;
|
||||
pub const __NDK_MINOR__: u32 = 0;
|
||||
pub const __NDK_BETA__: u32 = 0;
|
||||
pub const __NDK_BUILD__: u32 = 6352462;
|
||||
pub const __NDK_BUILD__: u32 = 8775105;
|
||||
pub const __NDK_CANARY__: u32 = 0;
|
||||
pub const POLLIN: u32 = 1;
|
||||
pub const POLLPRI: u32 = 2;
|
||||
@@ -306,6 +309,8 @@ pub const __SIGRTMAX: u32 = 64;
|
||||
pub const SA_NOCLDSTOP: u32 = 1;
|
||||
pub const SA_NOCLDWAIT: u32 = 2;
|
||||
pub const SA_SIGINFO: u32 = 4;
|
||||
pub const SA_UNSUPPORTED: u32 = 1024;
|
||||
pub const SA_EXPOSE_TAGBITS: u32 = 2048;
|
||||
pub const SA_ONSTACK: u32 = 134217728;
|
||||
pub const SA_RESTART: u32 = 268435456;
|
||||
pub const SA_NODEFER: u32 = 1073741824;
|
||||
@@ -361,7 +366,9 @@ pub const SEGV_PKUERR: u32 = 4;
|
||||
pub const SEGV_ACCADI: u32 = 5;
|
||||
pub const SEGV_ADIDERR: u32 = 6;
|
||||
pub const SEGV_ADIPERR: u32 = 7;
|
||||
pub const NSIGSEGV: u32 = 7;
|
||||
pub const SEGV_MTEAERR: u32 = 8;
|
||||
pub const SEGV_MTESERR: u32 = 9;
|
||||
pub const NSIGSEGV: u32 = 9;
|
||||
pub const BUS_ADRALN: u32 = 1;
|
||||
pub const BUS_ADRERR: u32 = 2;
|
||||
pub const BUS_OBJERR: u32 = 3;
|
||||
@@ -373,7 +380,8 @@ pub const TRAP_TRACE: u32 = 2;
|
||||
pub const TRAP_BRANCH: u32 = 3;
|
||||
pub const TRAP_HWBKPT: u32 = 4;
|
||||
pub const TRAP_UNK: u32 = 5;
|
||||
pub const NSIGTRAP: u32 = 5;
|
||||
pub const TRAP_PERF: u32 = 6;
|
||||
pub const NSIGTRAP: u32 = 6;
|
||||
pub const CLD_EXITED: u32 = 1;
|
||||
pub const CLD_KILLED: u32 = 2;
|
||||
pub const CLD_DUMPED: u32 = 3;
|
||||
@@ -389,7 +397,8 @@ pub const POLL_PRI: u32 = 5;
|
||||
pub const POLL_HUP: u32 = 6;
|
||||
pub const NSIGPOLL: u32 = 6;
|
||||
pub const SYS_SECCOMP: u32 = 1;
|
||||
pub const NSIGSYS: u32 = 1;
|
||||
pub const SYS_USER_DISPATCH: u32 = 2;
|
||||
pub const NSIGSYS: u32 = 2;
|
||||
pub const EMT_TAGOVF: u32 = 1;
|
||||
pub const NSIGEMT: u32 = 1;
|
||||
pub const SIGEV_SIGNAL: u32 = 0;
|
||||
@@ -453,6 +462,12 @@ pub const CLONE_NEWUSER: u32 = 268435456;
|
||||
pub const CLONE_NEWPID: u32 = 536870912;
|
||||
pub const CLONE_NEWNET: u32 = 1073741824;
|
||||
pub const CLONE_IO: u32 = 2147483648;
|
||||
pub const CLONE_CLEAR_SIGHAND: u64 = 4294967296;
|
||||
pub const CLONE_INTO_CGROUP: u64 = 8589934592;
|
||||
pub const CLONE_NEWTIME: u32 = 128;
|
||||
pub const CLONE_ARGS_SIZE_VER0: u32 = 64;
|
||||
pub const CLONE_ARGS_SIZE_VER1: u32 = 80;
|
||||
pub const CLONE_ARGS_SIZE_VER2: u32 = 88;
|
||||
pub const SCHED_NORMAL: u32 = 0;
|
||||
pub const SCHED_FIFO: u32 = 1;
|
||||
pub const SCHED_RR: u32 = 2;
|
||||
@@ -486,6 +501,9 @@ pub const PTHREAD_SCOPE_SYSTEM: u32 = 0;
|
||||
pub const PTHREAD_SCOPE_PROCESS: u32 = 1;
|
||||
pub const __GNUC_VA_LIST: u32 = 1;
|
||||
pub const AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT: u32 = 8;
|
||||
pub const true_: u32 = 1;
|
||||
pub const false_: u32 = 0;
|
||||
pub const __bool_true_false_are_defined: u32 = 1;
|
||||
pub const __PRI_64_prefix: &[u8; 2usize] = b"l\0";
|
||||
pub const __PRI_PTR_prefix: &[u8; 2usize] = b"l\0";
|
||||
pub const __PRI_FAST_prefix: &[u8; 2usize] = b"l\0";
|
||||
@@ -862,6 +880,7 @@ fn bindgen_test_layout___kernel_fsid_t() {
|
||||
}
|
||||
pub type __kernel_off_t = __kernel_long_t;
|
||||
pub type __kernel_loff_t = ::std::os::raw::c_longlong;
|
||||
pub type __kernel_old_time_t = __kernel_long_t;
|
||||
pub type __kernel_time_t = __kernel_long_t;
|
||||
pub type __kernel_time64_t = ::std::os::raw::c_longlong;
|
||||
pub type __kernel_clock_t = __kernel_long_t;
|
||||
@@ -1945,9 +1964,11 @@ pub struct __sifields__bindgen_ty_5 {
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub union __sifields__bindgen_ty_5__bindgen_ty_1 {
|
||||
pub _trapno: ::std::os::raw::c_int,
|
||||
pub _addr_lsb: ::std::os::raw::c_short,
|
||||
pub _addr_bnd: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1,
|
||||
pub _addr_pkey: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2,
|
||||
pub _perf: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3,
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -2065,6 +2086,57 @@ fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2() {
|
||||
)
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3 {
|
||||
pub _data: ::std::os::raw::c_ulong,
|
||||
pub _type: __u32,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>(),
|
||||
16usize,
|
||||
concat!(
|
||||
"Size of: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
::std::mem::align_of::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>(),
|
||||
8usize,
|
||||
concat!(
|
||||
"Alignment of ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>()))._data
|
||||
as *const _ as usize
|
||||
},
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3),
|
||||
"::",
|
||||
stringify!(_data)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>()))._type
|
||||
as *const _ as usize
|
||||
},
|
||||
8usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3),
|
||||
"::",
|
||||
stringify!(_type)
|
||||
)
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1() {
|
||||
assert_eq!(
|
||||
@@ -2083,6 +2155,19 @@ fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1() {
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1>()))._trapno as *const _
|
||||
as usize
|
||||
},
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1),
|
||||
"::",
|
||||
stringify!(_trapno)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1>()))._addr_lsb as *const _
|
||||
@@ -2122,6 +2207,19 @@ fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1() {
|
||||
stringify!(_addr_pkey)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1>()))._perf as *const _
|
||||
as usize
|
||||
},
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1),
|
||||
"::",
|
||||
stringify!(_perf)
|
||||
)
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout___sifields__bindgen_ty_5() {
|
||||
@@ -3384,40 +3482,40 @@ fn bindgen_test_layout___kernel_itimerspec() {
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct __kernel_old_timeval {
|
||||
pub tv_sec: __kernel_long_t,
|
||||
pub tv_usec: __kernel_long_t,
|
||||
pub struct __kernel_old_timespec {
|
||||
pub tv_sec: __kernel_old_time_t,
|
||||
pub tv_nsec: ::std::os::raw::c_long,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout___kernel_old_timeval() {
|
||||
fn bindgen_test_layout___kernel_old_timespec() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<__kernel_old_timeval>(),
|
||||
::std::mem::size_of::<__kernel_old_timespec>(),
|
||||
16usize,
|
||||
concat!("Size of: ", stringify!(__kernel_old_timeval))
|
||||
concat!("Size of: ", stringify!(__kernel_old_timespec))
|
||||
);
|
||||
assert_eq!(
|
||||
::std::mem::align_of::<__kernel_old_timeval>(),
|
||||
::std::mem::align_of::<__kernel_old_timespec>(),
|
||||
8usize,
|
||||
concat!("Alignment of ", stringify!(__kernel_old_timeval))
|
||||
concat!("Alignment of ", stringify!(__kernel_old_timespec))
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<__kernel_old_timeval>())).tv_sec as *const _ as usize },
|
||||
unsafe { &(*(::std::ptr::null::<__kernel_old_timespec>())).tv_sec as *const _ as usize },
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__kernel_old_timeval),
|
||||
stringify!(__kernel_old_timespec),
|
||||
"::",
|
||||
stringify!(tv_sec)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<__kernel_old_timeval>())).tv_usec as *const _ as usize },
|
||||
unsafe { &(*(::std::ptr::null::<__kernel_old_timespec>())).tv_nsec as *const _ as usize },
|
||||
8usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__kernel_old_timeval),
|
||||
stringify!(__kernel_old_timespec),
|
||||
"::",
|
||||
stringify!(tv_usec)
|
||||
stringify!(tv_nsec)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -3463,7 +3561,7 @@ fn bindgen_test_layout___kernel_sock_timeval() {
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct timeval {
|
||||
pub tv_sec: __kernel_time_t,
|
||||
pub tv_sec: __kernel_old_time_t,
|
||||
pub tv_usec: __kernel_suseconds_t,
|
||||
}
|
||||
#[test]
|
||||
@@ -3501,45 +3599,6 @@ fn bindgen_test_layout_timeval() {
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct timezone {
|
||||
pub tz_minuteswest: ::std::os::raw::c_int,
|
||||
pub tz_dsttime: ::std::os::raw::c_int,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_timezone() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<timezone>(),
|
||||
8usize,
|
||||
concat!("Size of: ", stringify!(timezone))
|
||||
);
|
||||
assert_eq!(
|
||||
::std::mem::align_of::<timezone>(),
|
||||
4usize,
|
||||
concat!("Alignment of ", stringify!(timezone))
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<timezone>())).tz_minuteswest as *const _ as usize },
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(timezone),
|
||||
"::",
|
||||
stringify!(tz_minuteswest)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<timezone>())).tz_dsttime as *const _ as usize },
|
||||
4usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(timezone),
|
||||
"::",
|
||||
stringify!(tz_dsttime)
|
||||
)
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct itimerspec {
|
||||
pub it_interval: timespec,
|
||||
pub it_value: timespec,
|
||||
@@ -3616,6 +3675,45 @@ fn bindgen_test_layout_itimerval() {
|
||||
)
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct timezone {
|
||||
pub tz_minuteswest: ::std::os::raw::c_int,
|
||||
pub tz_dsttime: ::std::os::raw::c_int,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_timezone() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<timezone>(),
|
||||
8usize,
|
||||
concat!("Size of: ", stringify!(timezone))
|
||||
);
|
||||
assert_eq!(
|
||||
::std::mem::align_of::<timezone>(),
|
||||
4usize,
|
||||
concat!("Alignment of ", stringify!(timezone))
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<timezone>())).tz_minuteswest as *const _ as usize },
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(timezone),
|
||||
"::",
|
||||
stringify!(tz_minuteswest)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<timezone>())).tz_dsttime as *const _ as usize },
|
||||
4usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(timezone),
|
||||
"::",
|
||||
stringify!(tz_dsttime)
|
||||
)
|
||||
);
|
||||
}
|
||||
pub type fd_mask = ::std::os::raw::c_ulong;
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -3660,7 +3758,7 @@ extern "C" {
|
||||
}
|
||||
extern "C" {
|
||||
pub fn select(
|
||||
__fd_count: ::std::os::raw::c_int,
|
||||
__max_fd_plus_one: ::std::os::raw::c_int,
|
||||
__read_fds: *mut fd_set,
|
||||
__write_fds: *mut fd_set,
|
||||
__exception_fds: *mut fd_set,
|
||||
@@ -3669,7 +3767,7 @@ extern "C" {
|
||||
}
|
||||
extern "C" {
|
||||
pub fn pselect(
|
||||
__fd_count: ::std::os::raw::c_int,
|
||||
__max_fd_plus_one: ::std::os::raw::c_int,
|
||||
__read_fds: *mut fd_set,
|
||||
__write_fds: *mut fd_set,
|
||||
__exception_fds: *mut fd_set,
|
||||
@@ -3679,7 +3777,7 @@ extern "C" {
|
||||
}
|
||||
extern "C" {
|
||||
pub fn pselect64(
|
||||
__fd_count: ::std::os::raw::c_int,
|
||||
__max_fd_plus_one: ::std::os::raw::c_int,
|
||||
__read_fds: *mut fd_set,
|
||||
__write_fds: *mut fd_set,
|
||||
__exception_fds: *mut fd_set,
|
||||
@@ -4039,12 +4137,15 @@ pub struct clone_args {
|
||||
pub stack: __u64,
|
||||
pub stack_size: __u64,
|
||||
pub tls: __u64,
|
||||
pub set_tid: __u64,
|
||||
pub set_tid_size: __u64,
|
||||
pub cgroup: __u64,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_clone_args() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<clone_args>(),
|
||||
64usize,
|
||||
88usize,
|
||||
concat!("Size of: ", stringify!(clone_args))
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -4132,6 +4233,36 @@ fn bindgen_test_layout_clone_args() {
|
||||
stringify!(tls)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<clone_args>())).set_tid as *const _ as usize },
|
||||
64usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(clone_args),
|
||||
"::",
|
||||
stringify!(set_tid)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<clone_args>())).set_tid_size as *const _ as usize },
|
||||
72usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(clone_args),
|
||||
"::",
|
||||
stringify!(set_tid_size)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<clone_args>())).cgroup as *const _ as usize },
|
||||
80usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(clone_args),
|
||||
"::",
|
||||
stringify!(cgroup)
|
||||
)
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -5345,6 +5476,10 @@ pub struct AInputEvent {
|
||||
}
|
||||
pub const AINPUT_EVENT_TYPE_KEY: ::std::os::raw::c_uint = 1;
|
||||
pub const AINPUT_EVENT_TYPE_MOTION: ::std::os::raw::c_uint = 2;
|
||||
pub const AINPUT_EVENT_TYPE_FOCUS: ::std::os::raw::c_uint = 3;
|
||||
pub const AINPUT_EVENT_TYPE_CAPTURE: ::std::os::raw::c_uint = 4;
|
||||
pub const AINPUT_EVENT_TYPE_DRAG: ::std::os::raw::c_uint = 5;
|
||||
pub const AINPUT_EVENT_TYPE_TOUCH_MODE: ::std::os::raw::c_uint = 6;
|
||||
pub type _bindgen_ty_11 = ::std::os::raw::c_uint;
|
||||
pub const AKEY_EVENT_ACTION_DOWN: ::std::os::raw::c_uint = 0;
|
||||
pub const AKEY_EVENT_ACTION_UP: ::std::os::raw::c_uint = 1;
|
||||
@@ -5445,7 +5580,13 @@ pub const AMOTION_EVENT_TOOL_TYPE_FINGER: ::std::os::raw::c_uint = 1;
|
||||
pub const AMOTION_EVENT_TOOL_TYPE_STYLUS: ::std::os::raw::c_uint = 2;
|
||||
pub const AMOTION_EVENT_TOOL_TYPE_MOUSE: ::std::os::raw::c_uint = 3;
|
||||
pub const AMOTION_EVENT_TOOL_TYPE_ERASER: ::std::os::raw::c_uint = 4;
|
||||
pub const AMOTION_EVENT_TOOL_TYPE_PALM: ::std::os::raw::c_uint = 5;
|
||||
pub type _bindgen_ty_19 = ::std::os::raw::c_uint;
|
||||
pub const AMotionClassification_AMOTION_EVENT_CLASSIFICATION_NONE: AMotionClassification = 0;
|
||||
pub const AMotionClassification_AMOTION_EVENT_CLASSIFICATION_AMBIGUOUS_GESTURE:
|
||||
AMotionClassification = 1;
|
||||
pub const AMotionClassification_AMOTION_EVENT_CLASSIFICATION_DEEP_PRESS: AMotionClassification = 2;
|
||||
pub type AMotionClassification = u32;
|
||||
pub const AINPUT_SOURCE_CLASS_MASK: ::std::os::raw::c_uint = 255;
|
||||
pub const AINPUT_SOURCE_CLASS_NONE: ::std::os::raw::c_uint = 0;
|
||||
pub const AINPUT_SOURCE_CLASS_BUTTON: ::std::os::raw::c_uint = 1;
|
||||
@@ -5467,6 +5608,8 @@ pub const AINPUT_SOURCE_MOUSE_RELATIVE: ::std::os::raw::c_uint = 131076;
|
||||
pub const AINPUT_SOURCE_TOUCHPAD: ::std::os::raw::c_uint = 1048584;
|
||||
pub const AINPUT_SOURCE_TOUCH_NAVIGATION: ::std::os::raw::c_uint = 2097152;
|
||||
pub const AINPUT_SOURCE_JOYSTICK: ::std::os::raw::c_uint = 16777232;
|
||||
pub const AINPUT_SOURCE_HDMI: ::std::os::raw::c_uint = 33554433;
|
||||
pub const AINPUT_SOURCE_SENSOR: ::std::os::raw::c_uint = 67108864;
|
||||
pub const AINPUT_SOURCE_ROTARY_ENCODER: ::std::os::raw::c_uint = 4194304;
|
||||
pub const AINPUT_SOURCE_ANY: ::std::os::raw::c_uint = 4294967040;
|
||||
pub type _bindgen_ty_21 = ::std::os::raw::c_uint;
|
||||
@@ -5493,6 +5636,9 @@ extern "C" {
|
||||
extern "C" {
|
||||
pub fn AInputEvent_getSource(event: *const AInputEvent) -> i32;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AInputEvent_release(event: *const AInputEvent);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AKeyEvent_getAction(key_event: *const AInputEvent) -> i32;
|
||||
}
|
||||
@@ -5517,6 +5663,9 @@ extern "C" {
|
||||
extern "C" {
|
||||
pub fn AKeyEvent_getEventTime(key_event: *const AInputEvent) -> i64;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AKeyEvent_fromJava(env: *mut JNIEnv, keyEvent: jobject) -> *const AInputEvent;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AMotionEvent_getAction(motion_event: *const AInputEvent) -> i32;
|
||||
}
|
||||
@@ -5713,6 +5862,15 @@ extern "C" {
|
||||
history_index: size_t,
|
||||
) -> f32;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AMotionEvent_getActionButton(motion_event: *const AInputEvent) -> i32;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AMotionEvent_getClassification(motion_event: *const AInputEvent) -> i32;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AMotionEvent_fromJava(env: *mut JNIEnv, motionEvent: jobject) -> *const AInputEvent;
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct imaxdiv_t {
|
||||
@@ -5787,11 +5945,52 @@ extern "C" {
|
||||
) -> uintmax_t;
|
||||
}
|
||||
pub const ADataSpace_ADATASPACE_UNKNOWN: ADataSpace = 0;
|
||||
pub const ADataSpace_STANDARD_MASK: ADataSpace = 4128768;
|
||||
pub const ADataSpace_STANDARD_UNSPECIFIED: ADataSpace = 0;
|
||||
pub const ADataSpace_STANDARD_BT709: ADataSpace = 65536;
|
||||
pub const ADataSpace_STANDARD_BT601_625: ADataSpace = 131072;
|
||||
pub const ADataSpace_STANDARD_BT601_625_UNADJUSTED: ADataSpace = 196608;
|
||||
pub const ADataSpace_STANDARD_BT601_525: ADataSpace = 262144;
|
||||
pub const ADataSpace_STANDARD_BT601_525_UNADJUSTED: ADataSpace = 327680;
|
||||
pub const ADataSpace_STANDARD_BT2020: ADataSpace = 393216;
|
||||
pub const ADataSpace_STANDARD_BT2020_CONSTANT_LUMINANCE: ADataSpace = 458752;
|
||||
pub const ADataSpace_STANDARD_BT470M: ADataSpace = 524288;
|
||||
pub const ADataSpace_STANDARD_FILM: ADataSpace = 589824;
|
||||
pub const ADataSpace_STANDARD_DCI_P3: ADataSpace = 655360;
|
||||
pub const ADataSpace_STANDARD_ADOBE_RGB: ADataSpace = 720896;
|
||||
pub const ADataSpace_TRANSFER_MASK: ADataSpace = 130023424;
|
||||
pub const ADataSpace_TRANSFER_UNSPECIFIED: ADataSpace = 0;
|
||||
pub const ADataSpace_TRANSFER_LINEAR: ADataSpace = 4194304;
|
||||
pub const ADataSpace_TRANSFER_SRGB: ADataSpace = 8388608;
|
||||
pub const ADataSpace_TRANSFER_SMPTE_170M: ADataSpace = 12582912;
|
||||
pub const ADataSpace_TRANSFER_GAMMA2_2: ADataSpace = 16777216;
|
||||
pub const ADataSpace_TRANSFER_GAMMA2_6: ADataSpace = 20971520;
|
||||
pub const ADataSpace_TRANSFER_GAMMA2_8: ADataSpace = 25165824;
|
||||
pub const ADataSpace_TRANSFER_ST2084: ADataSpace = 29360128;
|
||||
pub const ADataSpace_TRANSFER_HLG: ADataSpace = 33554432;
|
||||
pub const ADataSpace_RANGE_MASK: ADataSpace = 939524096;
|
||||
pub const ADataSpace_RANGE_UNSPECIFIED: ADataSpace = 0;
|
||||
pub const ADataSpace_RANGE_FULL: ADataSpace = 134217728;
|
||||
pub const ADataSpace_RANGE_LIMITED: ADataSpace = 268435456;
|
||||
pub const ADataSpace_RANGE_EXTENDED: ADataSpace = 402653184;
|
||||
pub const ADataSpace_ADATASPACE_SCRGB_LINEAR: ADataSpace = 406913024;
|
||||
pub const ADataSpace_ADATASPACE_SRGB: ADataSpace = 142671872;
|
||||
pub const ADataSpace_ADATASPACE_SCRGB: ADataSpace = 411107328;
|
||||
pub const ADataSpace_ADATASPACE_DISPLAY_P3: ADataSpace = 143261696;
|
||||
pub const ADataSpace_ADATASPACE_BT2020_PQ: ADataSpace = 163971072;
|
||||
pub const ADataSpace_ADATASPACE_BT2020_ITU_PQ: ADataSpace = 298188800;
|
||||
pub const ADataSpace_ADATASPACE_ADOBE_RGB: ADataSpace = 151715840;
|
||||
pub const ADataSpace_ADATASPACE_JFIF: ADataSpace = 146931712;
|
||||
pub const ADataSpace_ADATASPACE_BT601_625: ADataSpace = 281149440;
|
||||
pub const ADataSpace_ADATASPACE_BT601_525: ADataSpace = 281280512;
|
||||
pub const ADataSpace_ADATASPACE_BT2020: ADataSpace = 147193856;
|
||||
pub const ADataSpace_ADATASPACE_BT709: ADataSpace = 281083904;
|
||||
pub const ADataSpace_ADATASPACE_DCI_P3: ADataSpace = 155844608;
|
||||
pub const ADataSpace_ADATASPACE_SRGB_LINEAR: ADataSpace = 138477568;
|
||||
pub const ADataSpace_ADATASPACE_BT2020_HLG: ADataSpace = 168165376;
|
||||
pub const ADataSpace_ADATASPACE_BT2020_ITU_HLG: ADataSpace = 302383104;
|
||||
pub const ADataSpace_DEPTH: ADataSpace = 4096;
|
||||
pub const ADataSpace_DYNAMIC_DEPTH: ADataSpace = 4098;
|
||||
pub type ADataSpace = ::std::os::raw::c_uint;
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -5872,6 +6071,8 @@ pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT: AHard
|
||||
52;
|
||||
pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_S8_UINT: AHardwareBuffer_Format = 53;
|
||||
pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420: AHardwareBuffer_Format = 35;
|
||||
pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_YCbCr_P010: AHardwareBuffer_Format = 54;
|
||||
pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_R8_UNORM: AHardwareBuffer_Format = 56;
|
||||
pub type AHardwareBuffer_Format = ::std::os::raw::c_uint;
|
||||
pub const AHardwareBuffer_UsageFlags_AHARDWAREBUFFER_USAGE_CPU_READ_NEVER:
|
||||
AHardwareBuffer_UsageFlags = 0;
|
||||
@@ -6180,15 +6381,6 @@ extern "C" {
|
||||
outVirtualAddress: *mut *mut ::std::os::raw::c_void,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_lockPlanes(
|
||||
buffer: *mut AHardwareBuffer,
|
||||
usage: u64,
|
||||
fence: i32,
|
||||
rect: *const ARect,
|
||||
outPlanes: *mut AHardwareBuffer_Planes,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_unlock(
|
||||
buffer: *mut AHardwareBuffer,
|
||||
@@ -6207,6 +6399,15 @@ extern "C" {
|
||||
outBuffer: *mut *mut AHardwareBuffer,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_lockPlanes(
|
||||
buffer: *mut AHardwareBuffer,
|
||||
usage: u64,
|
||||
fence: i32,
|
||||
rect: *const ARect,
|
||||
outPlanes: *mut AHardwareBuffer_Planes,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_isSupported(desc: *const AHardwareBuffer_Desc) -> ::std::os::raw::c_int;
|
||||
}
|
||||
@@ -6221,6 +6422,12 @@ extern "C" {
|
||||
outBytesPerStride: *mut i32,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_getId(
|
||||
buffer: *const AHardwareBuffer,
|
||||
outId: *mut u64,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct ANativeActivity {
|
||||
pub callbacks: *mut ANativeActivityCallbacks,
|
||||
@@ -7148,6 +7355,12 @@ extern "C" {
|
||||
#[doc = " actions for the command before calling this function."]
|
||||
pub fn android_app_post_exec_cmd(android_app: *mut android_app, cmd: i8);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn android_app_attach_input_queue_looper(android_app: *mut android_app);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn android_app_detach_input_queue_looper(android_app: *mut android_app);
|
||||
}
|
||||
extern "C" {
|
||||
#[doc = " Dummy function that used to be used to prevent the linker from stripping app"]
|
||||
#[doc = " glue code. No longer necessary, since __attribute__((visibility(\"default\")))"]
|
||||
|
||||
@@ -101,10 +101,13 @@ pub const __ANDROID_API_O_MR1__: u32 = 27;
|
||||
pub const __ANDROID_API_P__: u32 = 28;
|
||||
pub const __ANDROID_API_Q__: u32 = 29;
|
||||
pub const __ANDROID_API_R__: u32 = 30;
|
||||
pub const __NDK_MAJOR__: u32 = 21;
|
||||
pub const __NDK_MINOR__: u32 = 1;
|
||||
pub const __ANDROID_API_S__: u32 = 31;
|
||||
pub const __ANDROID_API_T__: u32 = 33;
|
||||
pub const __ANDROID_NDK__: u32 = 1;
|
||||
pub const __NDK_MAJOR__: u32 = 25;
|
||||
pub const __NDK_MINOR__: u32 = 0;
|
||||
pub const __NDK_BETA__: u32 = 0;
|
||||
pub const __NDK_BUILD__: u32 = 6352462;
|
||||
pub const __NDK_BUILD__: u32 = 8775105;
|
||||
pub const __NDK_CANARY__: u32 = 0;
|
||||
pub const POLLIN: u32 = 1;
|
||||
pub const POLLPRI: u32 = 2;
|
||||
@@ -365,19 +368,21 @@ pub const SIGSYS: u32 = 31;
|
||||
pub const SIGUNUSED: u32 = 31;
|
||||
pub const __SIGRTMIN: u32 = 32;
|
||||
pub const SIGSWI: u32 = 32;
|
||||
pub const SA_THIRTYTWO: u32 = 33554432;
|
||||
pub const SA_RESTORER: u32 = 67108864;
|
||||
pub const MINSIGSTKSZ: u32 = 2048;
|
||||
pub const SIGSTKSZ: u32 = 8192;
|
||||
pub const SA_NOCLDSTOP: u32 = 1;
|
||||
pub const SA_NOCLDWAIT: u32 = 2;
|
||||
pub const SA_SIGINFO: u32 = 4;
|
||||
pub const SA_THIRTYTWO: u32 = 33554432;
|
||||
pub const SA_RESTORER: u32 = 67108864;
|
||||
pub const SA_UNSUPPORTED: u32 = 1024;
|
||||
pub const SA_EXPOSE_TAGBITS: u32 = 2048;
|
||||
pub const SA_ONSTACK: u32 = 134217728;
|
||||
pub const SA_RESTART: u32 = 268435456;
|
||||
pub const SA_NODEFER: u32 = 1073741824;
|
||||
pub const SA_RESETHAND: u32 = 2147483648;
|
||||
pub const SA_NOMASK: u32 = 1073741824;
|
||||
pub const SA_ONESHOT: u32 = 2147483648;
|
||||
pub const MINSIGSTKSZ: u32 = 2048;
|
||||
pub const SIGSTKSZ: u32 = 8192;
|
||||
pub const SIG_BLOCK: u32 = 0;
|
||||
pub const SIG_UNBLOCK: u32 = 1;
|
||||
pub const SIG_SETMASK: u32 = 2;
|
||||
@@ -427,7 +432,9 @@ pub const SEGV_PKUERR: u32 = 4;
|
||||
pub const SEGV_ACCADI: u32 = 5;
|
||||
pub const SEGV_ADIDERR: u32 = 6;
|
||||
pub const SEGV_ADIPERR: u32 = 7;
|
||||
pub const NSIGSEGV: u32 = 7;
|
||||
pub const SEGV_MTEAERR: u32 = 8;
|
||||
pub const SEGV_MTESERR: u32 = 9;
|
||||
pub const NSIGSEGV: u32 = 9;
|
||||
pub const BUS_ADRALN: u32 = 1;
|
||||
pub const BUS_ADRERR: u32 = 2;
|
||||
pub const BUS_OBJERR: u32 = 3;
|
||||
@@ -439,7 +446,8 @@ pub const TRAP_TRACE: u32 = 2;
|
||||
pub const TRAP_BRANCH: u32 = 3;
|
||||
pub const TRAP_HWBKPT: u32 = 4;
|
||||
pub const TRAP_UNK: u32 = 5;
|
||||
pub const NSIGTRAP: u32 = 5;
|
||||
pub const TRAP_PERF: u32 = 6;
|
||||
pub const NSIGTRAP: u32 = 6;
|
||||
pub const CLD_EXITED: u32 = 1;
|
||||
pub const CLD_KILLED: u32 = 2;
|
||||
pub const CLD_DUMPED: u32 = 3;
|
||||
@@ -455,7 +463,8 @@ pub const POLL_PRI: u32 = 5;
|
||||
pub const POLL_HUP: u32 = 6;
|
||||
pub const NSIGPOLL: u32 = 6;
|
||||
pub const SYS_SECCOMP: u32 = 1;
|
||||
pub const NSIGSYS: u32 = 1;
|
||||
pub const SYS_USER_DISPATCH: u32 = 2;
|
||||
pub const NSIGSYS: u32 = 2;
|
||||
pub const EMT_TAGOVF: u32 = 1;
|
||||
pub const NSIGEMT: u32 = 1;
|
||||
pub const SIGEV_SIGNAL: u32 = 0;
|
||||
@@ -520,6 +529,12 @@ pub const CLONE_NEWUSER: u32 = 268435456;
|
||||
pub const CLONE_NEWPID: u32 = 536870912;
|
||||
pub const CLONE_NEWNET: u32 = 1073741824;
|
||||
pub const CLONE_IO: u32 = 2147483648;
|
||||
pub const CLONE_CLEAR_SIGHAND: u64 = 4294967296;
|
||||
pub const CLONE_INTO_CGROUP: u64 = 8589934592;
|
||||
pub const CLONE_NEWTIME: u32 = 128;
|
||||
pub const CLONE_ARGS_SIZE_VER0: u32 = 64;
|
||||
pub const CLONE_ARGS_SIZE_VER1: u32 = 80;
|
||||
pub const CLONE_ARGS_SIZE_VER2: u32 = 88;
|
||||
pub const SCHED_NORMAL: u32 = 0;
|
||||
pub const SCHED_FIFO: u32 = 1;
|
||||
pub const SCHED_RR: u32 = 2;
|
||||
@@ -553,6 +568,9 @@ pub const PTHREAD_SCOPE_SYSTEM: u32 = 0;
|
||||
pub const PTHREAD_SCOPE_PROCESS: u32 = 1;
|
||||
pub const __GNUC_VA_LIST: u32 = 1;
|
||||
pub const AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT: u32 = 8;
|
||||
pub const true_: u32 = 1;
|
||||
pub const false_: u32 = 0;
|
||||
pub const __bool_true_false_are_defined: u32 = 1;
|
||||
pub const __PRI_64_prefix: &[u8; 3usize] = b"ll\0";
|
||||
pub const PRId8: &[u8; 2usize] = b"d\0";
|
||||
pub const PRId16: &[u8; 2usize] = b"d\0";
|
||||
@@ -892,6 +910,7 @@ fn bindgen_test_layout___kernel_fsid_t() {
|
||||
}
|
||||
pub type __kernel_off_t = __kernel_long_t;
|
||||
pub type __kernel_loff_t = ::std::os::raw::c_longlong;
|
||||
pub type __kernel_old_time_t = __kernel_long_t;
|
||||
pub type __kernel_time_t = __kernel_long_t;
|
||||
pub type __kernel_time64_t = ::std::os::raw::c_longlong;
|
||||
pub type __kernel_clock_t = __kernel_long_t;
|
||||
@@ -1902,9 +1921,11 @@ pub struct __sifields__bindgen_ty_5 {
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub union __sifields__bindgen_ty_5__bindgen_ty_1 {
|
||||
pub _trapno: ::std::os::raw::c_int,
|
||||
pub _addr_lsb: ::std::os::raw::c_short,
|
||||
pub _addr_bnd: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1,
|
||||
pub _addr_pkey: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2,
|
||||
pub _perf: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3,
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -2022,6 +2043,57 @@ fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2() {
|
||||
)
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3 {
|
||||
pub _data: ::std::os::raw::c_ulong,
|
||||
pub _type: __u32,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>(),
|
||||
8usize,
|
||||
concat!(
|
||||
"Size of: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
::std::mem::align_of::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>(),
|
||||
4usize,
|
||||
concat!(
|
||||
"Alignment of ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>()))._data
|
||||
as *const _ as usize
|
||||
},
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3),
|
||||
"::",
|
||||
stringify!(_data)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>()))._type
|
||||
as *const _ as usize
|
||||
},
|
||||
4usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3),
|
||||
"::",
|
||||
stringify!(_type)
|
||||
)
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1() {
|
||||
assert_eq!(
|
||||
@@ -2040,6 +2112,19 @@ fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1() {
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1>()))._trapno as *const _
|
||||
as usize
|
||||
},
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1),
|
||||
"::",
|
||||
stringify!(_trapno)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1>()))._addr_lsb as *const _
|
||||
@@ -2079,6 +2164,19 @@ fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1() {
|
||||
stringify!(_addr_pkey)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1>()))._perf as *const _
|
||||
as usize
|
||||
},
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1),
|
||||
"::",
|
||||
stringify!(_perf)
|
||||
)
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout___sifields__bindgen_ty_5() {
|
||||
@@ -3853,40 +3951,40 @@ fn bindgen_test_layout___kernel_itimerspec() {
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct __kernel_old_timeval {
|
||||
pub tv_sec: __kernel_long_t,
|
||||
pub tv_usec: __kernel_long_t,
|
||||
pub struct __kernel_old_timespec {
|
||||
pub tv_sec: __kernel_old_time_t,
|
||||
pub tv_nsec: ::std::os::raw::c_long,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout___kernel_old_timeval() {
|
||||
fn bindgen_test_layout___kernel_old_timespec() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<__kernel_old_timeval>(),
|
||||
::std::mem::size_of::<__kernel_old_timespec>(),
|
||||
8usize,
|
||||
concat!("Size of: ", stringify!(__kernel_old_timeval))
|
||||
concat!("Size of: ", stringify!(__kernel_old_timespec))
|
||||
);
|
||||
assert_eq!(
|
||||
::std::mem::align_of::<__kernel_old_timeval>(),
|
||||
::std::mem::align_of::<__kernel_old_timespec>(),
|
||||
4usize,
|
||||
concat!("Alignment of ", stringify!(__kernel_old_timeval))
|
||||
concat!("Alignment of ", stringify!(__kernel_old_timespec))
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<__kernel_old_timeval>())).tv_sec as *const _ as usize },
|
||||
unsafe { &(*(::std::ptr::null::<__kernel_old_timespec>())).tv_sec as *const _ as usize },
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__kernel_old_timeval),
|
||||
stringify!(__kernel_old_timespec),
|
||||
"::",
|
||||
stringify!(tv_sec)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<__kernel_old_timeval>())).tv_usec as *const _ as usize },
|
||||
unsafe { &(*(::std::ptr::null::<__kernel_old_timespec>())).tv_nsec as *const _ as usize },
|
||||
4usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__kernel_old_timeval),
|
||||
stringify!(__kernel_old_timespec),
|
||||
"::",
|
||||
stringify!(tv_usec)
|
||||
stringify!(tv_nsec)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -3932,7 +4030,7 @@ fn bindgen_test_layout___kernel_sock_timeval() {
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct timeval {
|
||||
pub tv_sec: __kernel_time_t,
|
||||
pub tv_sec: __kernel_old_time_t,
|
||||
pub tv_usec: __kernel_suseconds_t,
|
||||
}
|
||||
#[test]
|
||||
@@ -3970,45 +4068,6 @@ fn bindgen_test_layout_timeval() {
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct timezone {
|
||||
pub tz_minuteswest: ::std::os::raw::c_int,
|
||||
pub tz_dsttime: ::std::os::raw::c_int,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_timezone() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<timezone>(),
|
||||
8usize,
|
||||
concat!("Size of: ", stringify!(timezone))
|
||||
);
|
||||
assert_eq!(
|
||||
::std::mem::align_of::<timezone>(),
|
||||
4usize,
|
||||
concat!("Alignment of ", stringify!(timezone))
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<timezone>())).tz_minuteswest as *const _ as usize },
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(timezone),
|
||||
"::",
|
||||
stringify!(tz_minuteswest)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<timezone>())).tz_dsttime as *const _ as usize },
|
||||
4usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(timezone),
|
||||
"::",
|
||||
stringify!(tz_dsttime)
|
||||
)
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct itimerspec {
|
||||
pub it_interval: timespec,
|
||||
pub it_value: timespec,
|
||||
@@ -4085,6 +4144,45 @@ fn bindgen_test_layout_itimerval() {
|
||||
)
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct timezone {
|
||||
pub tz_minuteswest: ::std::os::raw::c_int,
|
||||
pub tz_dsttime: ::std::os::raw::c_int,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_timezone() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<timezone>(),
|
||||
8usize,
|
||||
concat!("Size of: ", stringify!(timezone))
|
||||
);
|
||||
assert_eq!(
|
||||
::std::mem::align_of::<timezone>(),
|
||||
4usize,
|
||||
concat!("Alignment of ", stringify!(timezone))
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<timezone>())).tz_minuteswest as *const _ as usize },
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(timezone),
|
||||
"::",
|
||||
stringify!(tz_minuteswest)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<timezone>())).tz_dsttime as *const _ as usize },
|
||||
4usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(timezone),
|
||||
"::",
|
||||
stringify!(tz_dsttime)
|
||||
)
|
||||
);
|
||||
}
|
||||
pub type fd_mask = ::std::os::raw::c_ulong;
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -4129,7 +4227,7 @@ extern "C" {
|
||||
}
|
||||
extern "C" {
|
||||
pub fn select(
|
||||
__fd_count: ::std::os::raw::c_int,
|
||||
__max_fd_plus_one: ::std::os::raw::c_int,
|
||||
__read_fds: *mut fd_set,
|
||||
__write_fds: *mut fd_set,
|
||||
__exception_fds: *mut fd_set,
|
||||
@@ -4138,7 +4236,7 @@ extern "C" {
|
||||
}
|
||||
extern "C" {
|
||||
pub fn pselect(
|
||||
__fd_count: ::std::os::raw::c_int,
|
||||
__max_fd_plus_one: ::std::os::raw::c_int,
|
||||
__read_fds: *mut fd_set,
|
||||
__write_fds: *mut fd_set,
|
||||
__exception_fds: *mut fd_set,
|
||||
@@ -4148,7 +4246,7 @@ extern "C" {
|
||||
}
|
||||
extern "C" {
|
||||
pub fn pselect64(
|
||||
__fd_count: ::std::os::raw::c_int,
|
||||
__max_fd_plus_one: ::std::os::raw::c_int,
|
||||
__read_fds: *mut fd_set,
|
||||
__write_fds: *mut fd_set,
|
||||
__exception_fds: *mut fd_set,
|
||||
@@ -4508,12 +4606,15 @@ pub struct clone_args {
|
||||
pub stack: __u64,
|
||||
pub stack_size: __u64,
|
||||
pub tls: __u64,
|
||||
pub set_tid: __u64,
|
||||
pub set_tid_size: __u64,
|
||||
pub cgroup: __u64,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_clone_args() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<clone_args>(),
|
||||
64usize,
|
||||
88usize,
|
||||
concat!("Size of: ", stringify!(clone_args))
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -4601,6 +4702,36 @@ fn bindgen_test_layout_clone_args() {
|
||||
stringify!(tls)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<clone_args>())).set_tid as *const _ as usize },
|
||||
64usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(clone_args),
|
||||
"::",
|
||||
stringify!(set_tid)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<clone_args>())).set_tid_size as *const _ as usize },
|
||||
72usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(clone_args),
|
||||
"::",
|
||||
stringify!(set_tid_size)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<clone_args>())).cgroup as *const _ as usize },
|
||||
80usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(clone_args),
|
||||
"::",
|
||||
stringify!(cgroup)
|
||||
)
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -5814,6 +5945,10 @@ pub struct AInputEvent {
|
||||
}
|
||||
pub const AINPUT_EVENT_TYPE_KEY: ::std::os::raw::c_uint = 1;
|
||||
pub const AINPUT_EVENT_TYPE_MOTION: ::std::os::raw::c_uint = 2;
|
||||
pub const AINPUT_EVENT_TYPE_FOCUS: ::std::os::raw::c_uint = 3;
|
||||
pub const AINPUT_EVENT_TYPE_CAPTURE: ::std::os::raw::c_uint = 4;
|
||||
pub const AINPUT_EVENT_TYPE_DRAG: ::std::os::raw::c_uint = 5;
|
||||
pub const AINPUT_EVENT_TYPE_TOUCH_MODE: ::std::os::raw::c_uint = 6;
|
||||
pub type _bindgen_ty_12 = ::std::os::raw::c_uint;
|
||||
pub const AKEY_EVENT_ACTION_DOWN: ::std::os::raw::c_uint = 0;
|
||||
pub const AKEY_EVENT_ACTION_UP: ::std::os::raw::c_uint = 1;
|
||||
@@ -5914,7 +6049,13 @@ pub const AMOTION_EVENT_TOOL_TYPE_FINGER: ::std::os::raw::c_uint = 1;
|
||||
pub const AMOTION_EVENT_TOOL_TYPE_STYLUS: ::std::os::raw::c_uint = 2;
|
||||
pub const AMOTION_EVENT_TOOL_TYPE_MOUSE: ::std::os::raw::c_uint = 3;
|
||||
pub const AMOTION_EVENT_TOOL_TYPE_ERASER: ::std::os::raw::c_uint = 4;
|
||||
pub const AMOTION_EVENT_TOOL_TYPE_PALM: ::std::os::raw::c_uint = 5;
|
||||
pub type _bindgen_ty_20 = ::std::os::raw::c_uint;
|
||||
pub const AMotionClassification_AMOTION_EVENT_CLASSIFICATION_NONE: AMotionClassification = 0;
|
||||
pub const AMotionClassification_AMOTION_EVENT_CLASSIFICATION_AMBIGUOUS_GESTURE:
|
||||
AMotionClassification = 1;
|
||||
pub const AMotionClassification_AMOTION_EVENT_CLASSIFICATION_DEEP_PRESS: AMotionClassification = 2;
|
||||
pub type AMotionClassification = u32;
|
||||
pub const AINPUT_SOURCE_CLASS_MASK: ::std::os::raw::c_uint = 255;
|
||||
pub const AINPUT_SOURCE_CLASS_NONE: ::std::os::raw::c_uint = 0;
|
||||
pub const AINPUT_SOURCE_CLASS_BUTTON: ::std::os::raw::c_uint = 1;
|
||||
@@ -5936,6 +6077,8 @@ pub const AINPUT_SOURCE_MOUSE_RELATIVE: ::std::os::raw::c_uint = 131076;
|
||||
pub const AINPUT_SOURCE_TOUCHPAD: ::std::os::raw::c_uint = 1048584;
|
||||
pub const AINPUT_SOURCE_TOUCH_NAVIGATION: ::std::os::raw::c_uint = 2097152;
|
||||
pub const AINPUT_SOURCE_JOYSTICK: ::std::os::raw::c_uint = 16777232;
|
||||
pub const AINPUT_SOURCE_HDMI: ::std::os::raw::c_uint = 33554433;
|
||||
pub const AINPUT_SOURCE_SENSOR: ::std::os::raw::c_uint = 67108864;
|
||||
pub const AINPUT_SOURCE_ROTARY_ENCODER: ::std::os::raw::c_uint = 4194304;
|
||||
pub const AINPUT_SOURCE_ANY: ::std::os::raw::c_uint = 4294967040;
|
||||
pub type _bindgen_ty_22 = ::std::os::raw::c_uint;
|
||||
@@ -5962,6 +6105,9 @@ extern "C" {
|
||||
extern "C" {
|
||||
pub fn AInputEvent_getSource(event: *const AInputEvent) -> i32;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AInputEvent_release(event: *const AInputEvent);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AKeyEvent_getAction(key_event: *const AInputEvent) -> i32;
|
||||
}
|
||||
@@ -5986,6 +6132,9 @@ extern "C" {
|
||||
extern "C" {
|
||||
pub fn AKeyEvent_getEventTime(key_event: *const AInputEvent) -> i64;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AKeyEvent_fromJava(env: *mut JNIEnv, keyEvent: jobject) -> *const AInputEvent;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AMotionEvent_getAction(motion_event: *const AInputEvent) -> i32;
|
||||
}
|
||||
@@ -6182,6 +6331,15 @@ extern "C" {
|
||||
history_index: size_t,
|
||||
) -> f32;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AMotionEvent_getActionButton(motion_event: *const AInputEvent) -> i32;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AMotionEvent_getClassification(motion_event: *const AInputEvent) -> i32;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AMotionEvent_fromJava(env: *mut JNIEnv, motionEvent: jobject) -> *const AInputEvent;
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct imaxdiv_t {
|
||||
@@ -6256,11 +6414,52 @@ extern "C" {
|
||||
) -> uintmax_t;
|
||||
}
|
||||
pub const ADataSpace_ADATASPACE_UNKNOWN: ADataSpace = 0;
|
||||
pub const ADataSpace_STANDARD_MASK: ADataSpace = 4128768;
|
||||
pub const ADataSpace_STANDARD_UNSPECIFIED: ADataSpace = 0;
|
||||
pub const ADataSpace_STANDARD_BT709: ADataSpace = 65536;
|
||||
pub const ADataSpace_STANDARD_BT601_625: ADataSpace = 131072;
|
||||
pub const ADataSpace_STANDARD_BT601_625_UNADJUSTED: ADataSpace = 196608;
|
||||
pub const ADataSpace_STANDARD_BT601_525: ADataSpace = 262144;
|
||||
pub const ADataSpace_STANDARD_BT601_525_UNADJUSTED: ADataSpace = 327680;
|
||||
pub const ADataSpace_STANDARD_BT2020: ADataSpace = 393216;
|
||||
pub const ADataSpace_STANDARD_BT2020_CONSTANT_LUMINANCE: ADataSpace = 458752;
|
||||
pub const ADataSpace_STANDARD_BT470M: ADataSpace = 524288;
|
||||
pub const ADataSpace_STANDARD_FILM: ADataSpace = 589824;
|
||||
pub const ADataSpace_STANDARD_DCI_P3: ADataSpace = 655360;
|
||||
pub const ADataSpace_STANDARD_ADOBE_RGB: ADataSpace = 720896;
|
||||
pub const ADataSpace_TRANSFER_MASK: ADataSpace = 130023424;
|
||||
pub const ADataSpace_TRANSFER_UNSPECIFIED: ADataSpace = 0;
|
||||
pub const ADataSpace_TRANSFER_LINEAR: ADataSpace = 4194304;
|
||||
pub const ADataSpace_TRANSFER_SRGB: ADataSpace = 8388608;
|
||||
pub const ADataSpace_TRANSFER_SMPTE_170M: ADataSpace = 12582912;
|
||||
pub const ADataSpace_TRANSFER_GAMMA2_2: ADataSpace = 16777216;
|
||||
pub const ADataSpace_TRANSFER_GAMMA2_6: ADataSpace = 20971520;
|
||||
pub const ADataSpace_TRANSFER_GAMMA2_8: ADataSpace = 25165824;
|
||||
pub const ADataSpace_TRANSFER_ST2084: ADataSpace = 29360128;
|
||||
pub const ADataSpace_TRANSFER_HLG: ADataSpace = 33554432;
|
||||
pub const ADataSpace_RANGE_MASK: ADataSpace = 939524096;
|
||||
pub const ADataSpace_RANGE_UNSPECIFIED: ADataSpace = 0;
|
||||
pub const ADataSpace_RANGE_FULL: ADataSpace = 134217728;
|
||||
pub const ADataSpace_RANGE_LIMITED: ADataSpace = 268435456;
|
||||
pub const ADataSpace_RANGE_EXTENDED: ADataSpace = 402653184;
|
||||
pub const ADataSpace_ADATASPACE_SCRGB_LINEAR: ADataSpace = 406913024;
|
||||
pub const ADataSpace_ADATASPACE_SRGB: ADataSpace = 142671872;
|
||||
pub const ADataSpace_ADATASPACE_SCRGB: ADataSpace = 411107328;
|
||||
pub const ADataSpace_ADATASPACE_DISPLAY_P3: ADataSpace = 143261696;
|
||||
pub const ADataSpace_ADATASPACE_BT2020_PQ: ADataSpace = 163971072;
|
||||
pub const ADataSpace_ADATASPACE_BT2020_ITU_PQ: ADataSpace = 298188800;
|
||||
pub const ADataSpace_ADATASPACE_ADOBE_RGB: ADataSpace = 151715840;
|
||||
pub const ADataSpace_ADATASPACE_JFIF: ADataSpace = 146931712;
|
||||
pub const ADataSpace_ADATASPACE_BT601_625: ADataSpace = 281149440;
|
||||
pub const ADataSpace_ADATASPACE_BT601_525: ADataSpace = 281280512;
|
||||
pub const ADataSpace_ADATASPACE_BT2020: ADataSpace = 147193856;
|
||||
pub const ADataSpace_ADATASPACE_BT709: ADataSpace = 281083904;
|
||||
pub const ADataSpace_ADATASPACE_DCI_P3: ADataSpace = 155844608;
|
||||
pub const ADataSpace_ADATASPACE_SRGB_LINEAR: ADataSpace = 138477568;
|
||||
pub const ADataSpace_ADATASPACE_BT2020_HLG: ADataSpace = 168165376;
|
||||
pub const ADataSpace_ADATASPACE_BT2020_ITU_HLG: ADataSpace = 302383104;
|
||||
pub const ADataSpace_DEPTH: ADataSpace = 4096;
|
||||
pub const ADataSpace_DYNAMIC_DEPTH: ADataSpace = 4098;
|
||||
pub type ADataSpace = ::std::os::raw::c_uint;
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -6341,6 +6540,8 @@ pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT: AHard
|
||||
52;
|
||||
pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_S8_UINT: AHardwareBuffer_Format = 53;
|
||||
pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420: AHardwareBuffer_Format = 35;
|
||||
pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_YCbCr_P010: AHardwareBuffer_Format = 54;
|
||||
pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_R8_UNORM: AHardwareBuffer_Format = 56;
|
||||
pub type AHardwareBuffer_Format = ::std::os::raw::c_uint;
|
||||
pub const AHardwareBuffer_UsageFlags_AHARDWAREBUFFER_USAGE_CPU_READ_NEVER:
|
||||
AHardwareBuffer_UsageFlags = 0;
|
||||
@@ -6649,15 +6850,6 @@ extern "C" {
|
||||
outVirtualAddress: *mut *mut ::std::os::raw::c_void,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_lockPlanes(
|
||||
buffer: *mut AHardwareBuffer,
|
||||
usage: u64,
|
||||
fence: i32,
|
||||
rect: *const ARect,
|
||||
outPlanes: *mut AHardwareBuffer_Planes,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_unlock(
|
||||
buffer: *mut AHardwareBuffer,
|
||||
@@ -6676,6 +6868,15 @@ extern "C" {
|
||||
outBuffer: *mut *mut AHardwareBuffer,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_lockPlanes(
|
||||
buffer: *mut AHardwareBuffer,
|
||||
usage: u64,
|
||||
fence: i32,
|
||||
rect: *const ARect,
|
||||
outPlanes: *mut AHardwareBuffer_Planes,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_isSupported(desc: *const AHardwareBuffer_Desc) -> ::std::os::raw::c_int;
|
||||
}
|
||||
@@ -6690,6 +6891,12 @@ extern "C" {
|
||||
outBytesPerStride: *mut i32,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_getId(
|
||||
buffer: *const AHardwareBuffer,
|
||||
outId: *mut u64,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct ANativeActivity {
|
||||
pub callbacks: *mut ANativeActivityCallbacks,
|
||||
@@ -7617,6 +7824,12 @@ extern "C" {
|
||||
#[doc = " actions for the command before calling this function."]
|
||||
pub fn android_app_post_exec_cmd(android_app: *mut android_app, cmd: i8);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn android_app_attach_input_queue_looper(android_app: *mut android_app);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn android_app_detach_input_queue_looper(android_app: *mut android_app);
|
||||
}
|
||||
extern "C" {
|
||||
#[doc = " Dummy function that used to be used to prevent the linker from stripping app"]
|
||||
#[doc = " glue code. No longer necessary, since __attribute__((visibility(\"default\")))"]
|
||||
|
||||
@@ -21,10 +21,13 @@ pub const __ANDROID_API_O_MR1__: u32 = 27;
|
||||
pub const __ANDROID_API_P__: u32 = 28;
|
||||
pub const __ANDROID_API_Q__: u32 = 29;
|
||||
pub const __ANDROID_API_R__: u32 = 30;
|
||||
pub const __NDK_MAJOR__: u32 = 21;
|
||||
pub const __NDK_MINOR__: u32 = 1;
|
||||
pub const __ANDROID_API_S__: u32 = 31;
|
||||
pub const __ANDROID_API_T__: u32 = 33;
|
||||
pub const __ANDROID_NDK__: u32 = 1;
|
||||
pub const __NDK_MAJOR__: u32 = 25;
|
||||
pub const __NDK_MINOR__: u32 = 0;
|
||||
pub const __NDK_BETA__: u32 = 0;
|
||||
pub const __NDK_BUILD__: u32 = 6352462;
|
||||
pub const __NDK_BUILD__: u32 = 8775105;
|
||||
pub const __NDK_CANARY__: u32 = 0;
|
||||
pub const POLLIN: u32 = 1;
|
||||
pub const POLLPRI: u32 = 2;
|
||||
@@ -305,18 +308,20 @@ pub const SIGPWR: u32 = 30;
|
||||
pub const SIGSYS: u32 = 31;
|
||||
pub const SIGUNUSED: u32 = 31;
|
||||
pub const __SIGRTMIN: u32 = 32;
|
||||
pub const SA_RESTORER: u32 = 67108864;
|
||||
pub const MINSIGSTKSZ: u32 = 2048;
|
||||
pub const SIGSTKSZ: u32 = 8192;
|
||||
pub const SA_NOCLDSTOP: u32 = 1;
|
||||
pub const SA_NOCLDWAIT: u32 = 2;
|
||||
pub const SA_SIGINFO: u32 = 4;
|
||||
pub const SA_UNSUPPORTED: u32 = 1024;
|
||||
pub const SA_EXPOSE_TAGBITS: u32 = 2048;
|
||||
pub const SA_ONSTACK: u32 = 134217728;
|
||||
pub const SA_RESTART: u32 = 268435456;
|
||||
pub const SA_NODEFER: u32 = 1073741824;
|
||||
pub const SA_RESETHAND: u32 = 2147483648;
|
||||
pub const SA_NOMASK: u32 = 1073741824;
|
||||
pub const SA_ONESHOT: u32 = 2147483648;
|
||||
pub const SA_RESTORER: u32 = 67108864;
|
||||
pub const MINSIGSTKSZ: u32 = 2048;
|
||||
pub const SIGSTKSZ: u32 = 8192;
|
||||
pub const SIG_BLOCK: u32 = 0;
|
||||
pub const SIG_UNBLOCK: u32 = 1;
|
||||
pub const SIG_SETMASK: u32 = 2;
|
||||
@@ -366,7 +371,9 @@ pub const SEGV_PKUERR: u32 = 4;
|
||||
pub const SEGV_ACCADI: u32 = 5;
|
||||
pub const SEGV_ADIDERR: u32 = 6;
|
||||
pub const SEGV_ADIPERR: u32 = 7;
|
||||
pub const NSIGSEGV: u32 = 7;
|
||||
pub const SEGV_MTEAERR: u32 = 8;
|
||||
pub const SEGV_MTESERR: u32 = 9;
|
||||
pub const NSIGSEGV: u32 = 9;
|
||||
pub const BUS_ADRALN: u32 = 1;
|
||||
pub const BUS_ADRERR: u32 = 2;
|
||||
pub const BUS_OBJERR: u32 = 3;
|
||||
@@ -378,7 +385,8 @@ pub const TRAP_TRACE: u32 = 2;
|
||||
pub const TRAP_BRANCH: u32 = 3;
|
||||
pub const TRAP_HWBKPT: u32 = 4;
|
||||
pub const TRAP_UNK: u32 = 5;
|
||||
pub const NSIGTRAP: u32 = 5;
|
||||
pub const TRAP_PERF: u32 = 6;
|
||||
pub const NSIGTRAP: u32 = 6;
|
||||
pub const CLD_EXITED: u32 = 1;
|
||||
pub const CLD_KILLED: u32 = 2;
|
||||
pub const CLD_DUMPED: u32 = 3;
|
||||
@@ -394,7 +402,8 @@ pub const POLL_PRI: u32 = 5;
|
||||
pub const POLL_HUP: u32 = 6;
|
||||
pub const NSIGPOLL: u32 = 6;
|
||||
pub const SYS_SECCOMP: u32 = 1;
|
||||
pub const NSIGSYS: u32 = 1;
|
||||
pub const SYS_USER_DISPATCH: u32 = 2;
|
||||
pub const NSIGSYS: u32 = 2;
|
||||
pub const EMT_TAGOVF: u32 = 1;
|
||||
pub const NSIGEMT: u32 = 1;
|
||||
pub const SIGEV_SIGNAL: u32 = 0;
|
||||
@@ -440,6 +449,12 @@ pub const CLONE_NEWUSER: u32 = 268435456;
|
||||
pub const CLONE_NEWPID: u32 = 536870912;
|
||||
pub const CLONE_NEWNET: u32 = 1073741824;
|
||||
pub const CLONE_IO: u32 = 2147483648;
|
||||
pub const CLONE_CLEAR_SIGHAND: u64 = 4294967296;
|
||||
pub const CLONE_INTO_CGROUP: u64 = 8589934592;
|
||||
pub const CLONE_NEWTIME: u32 = 128;
|
||||
pub const CLONE_ARGS_SIZE_VER0: u32 = 64;
|
||||
pub const CLONE_ARGS_SIZE_VER1: u32 = 80;
|
||||
pub const CLONE_ARGS_SIZE_VER2: u32 = 88;
|
||||
pub const SCHED_NORMAL: u32 = 0;
|
||||
pub const SCHED_FIFO: u32 = 1;
|
||||
pub const SCHED_RR: u32 = 2;
|
||||
@@ -473,6 +488,9 @@ pub const PTHREAD_SCOPE_SYSTEM: u32 = 0;
|
||||
pub const PTHREAD_SCOPE_PROCESS: u32 = 1;
|
||||
pub const __GNUC_VA_LIST: u32 = 1;
|
||||
pub const AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT: u32 = 8;
|
||||
pub const true_: u32 = 1;
|
||||
pub const false_: u32 = 0;
|
||||
pub const __bool_true_false_are_defined: u32 = 1;
|
||||
pub const __PRI_64_prefix: &[u8; 3usize] = b"ll\0";
|
||||
pub const PRId8: &[u8; 2usize] = b"d\0";
|
||||
pub const PRId16: &[u8; 2usize] = b"d\0";
|
||||
@@ -813,6 +831,7 @@ fn bindgen_test_layout___kernel_fsid_t() {
|
||||
}
|
||||
pub type __kernel_off_t = __kernel_long_t;
|
||||
pub type __kernel_loff_t = ::std::os::raw::c_longlong;
|
||||
pub type __kernel_old_time_t = __kernel_long_t;
|
||||
pub type __kernel_time_t = __kernel_long_t;
|
||||
pub type __kernel_time64_t = ::std::os::raw::c_longlong;
|
||||
pub type __kernel_clock_t = __kernel_long_t;
|
||||
@@ -2936,40 +2955,40 @@ fn bindgen_test_layout___kernel_itimerspec() {
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct __kernel_old_timeval {
|
||||
pub tv_sec: __kernel_long_t,
|
||||
pub tv_usec: __kernel_long_t,
|
||||
pub struct __kernel_old_timespec {
|
||||
pub tv_sec: __kernel_old_time_t,
|
||||
pub tv_nsec: ::std::os::raw::c_long,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout___kernel_old_timeval() {
|
||||
fn bindgen_test_layout___kernel_old_timespec() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<__kernel_old_timeval>(),
|
||||
::std::mem::size_of::<__kernel_old_timespec>(),
|
||||
8usize,
|
||||
concat!("Size of: ", stringify!(__kernel_old_timeval))
|
||||
concat!("Size of: ", stringify!(__kernel_old_timespec))
|
||||
);
|
||||
assert_eq!(
|
||||
::std::mem::align_of::<__kernel_old_timeval>(),
|
||||
::std::mem::align_of::<__kernel_old_timespec>(),
|
||||
4usize,
|
||||
concat!("Alignment of ", stringify!(__kernel_old_timeval))
|
||||
concat!("Alignment of ", stringify!(__kernel_old_timespec))
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<__kernel_old_timeval>())).tv_sec as *const _ as usize },
|
||||
unsafe { &(*(::std::ptr::null::<__kernel_old_timespec>())).tv_sec as *const _ as usize },
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__kernel_old_timeval),
|
||||
stringify!(__kernel_old_timespec),
|
||||
"::",
|
||||
stringify!(tv_sec)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<__kernel_old_timeval>())).tv_usec as *const _ as usize },
|
||||
unsafe { &(*(::std::ptr::null::<__kernel_old_timespec>())).tv_nsec as *const _ as usize },
|
||||
4usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__kernel_old_timeval),
|
||||
stringify!(__kernel_old_timespec),
|
||||
"::",
|
||||
stringify!(tv_usec)
|
||||
stringify!(tv_nsec)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -3015,7 +3034,7 @@ fn bindgen_test_layout___kernel_sock_timeval() {
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct timespec {
|
||||
pub tv_sec: __kernel_time_t,
|
||||
pub tv_sec: __kernel_old_time_t,
|
||||
pub tv_nsec: ::std::os::raw::c_long,
|
||||
}
|
||||
#[test]
|
||||
@@ -3054,7 +3073,7 @@ fn bindgen_test_layout_timespec() {
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct timeval {
|
||||
pub tv_sec: __kernel_time_t,
|
||||
pub tv_sec: __kernel_old_time_t,
|
||||
pub tv_usec: __kernel_suseconds_t,
|
||||
}
|
||||
#[test]
|
||||
@@ -3092,45 +3111,6 @@ fn bindgen_test_layout_timeval() {
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct timezone {
|
||||
pub tz_minuteswest: ::std::os::raw::c_int,
|
||||
pub tz_dsttime: ::std::os::raw::c_int,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_timezone() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<timezone>(),
|
||||
8usize,
|
||||
concat!("Size of: ", stringify!(timezone))
|
||||
);
|
||||
assert_eq!(
|
||||
::std::mem::align_of::<timezone>(),
|
||||
4usize,
|
||||
concat!("Alignment of ", stringify!(timezone))
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<timezone>())).tz_minuteswest as *const _ as usize },
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(timezone),
|
||||
"::",
|
||||
stringify!(tz_minuteswest)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<timezone>())).tz_dsttime as *const _ as usize },
|
||||
4usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(timezone),
|
||||
"::",
|
||||
stringify!(tz_dsttime)
|
||||
)
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct itimerspec {
|
||||
pub it_interval: timespec,
|
||||
pub it_value: timespec,
|
||||
@@ -3207,6 +3187,45 @@ fn bindgen_test_layout_itimerval() {
|
||||
)
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct timezone {
|
||||
pub tz_minuteswest: ::std::os::raw::c_int,
|
||||
pub tz_dsttime: ::std::os::raw::c_int,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_timezone() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<timezone>(),
|
||||
8usize,
|
||||
concat!("Size of: ", stringify!(timezone))
|
||||
);
|
||||
assert_eq!(
|
||||
::std::mem::align_of::<timezone>(),
|
||||
4usize,
|
||||
concat!("Alignment of ", stringify!(timezone))
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<timezone>())).tz_minuteswest as *const _ as usize },
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(timezone),
|
||||
"::",
|
||||
stringify!(tz_minuteswest)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<timezone>())).tz_dsttime as *const _ as usize },
|
||||
4usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(timezone),
|
||||
"::",
|
||||
stringify!(tz_dsttime)
|
||||
)
|
||||
);
|
||||
}
|
||||
pub type sigset_t = ::std::os::raw::c_ulong;
|
||||
pub type __signalfn_t = ::std::option::Option<unsafe extern "C" fn(arg1: ::std::os::raw::c_int)>;
|
||||
pub type __sighandler_t = __signalfn_t;
|
||||
@@ -3670,9 +3689,11 @@ pub struct __sifields__bindgen_ty_5 {
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub union __sifields__bindgen_ty_5__bindgen_ty_1 {
|
||||
pub _trapno: ::std::os::raw::c_int,
|
||||
pub _addr_lsb: ::std::os::raw::c_short,
|
||||
pub _addr_bnd: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1,
|
||||
pub _addr_pkey: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2,
|
||||
pub _perf: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3,
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -3790,6 +3811,57 @@ fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2() {
|
||||
)
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3 {
|
||||
pub _data: ::std::os::raw::c_ulong,
|
||||
pub _type: __u32,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>(),
|
||||
8usize,
|
||||
concat!(
|
||||
"Size of: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
::std::mem::align_of::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>(),
|
||||
4usize,
|
||||
concat!(
|
||||
"Alignment of ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>()))._data
|
||||
as *const _ as usize
|
||||
},
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3),
|
||||
"::",
|
||||
stringify!(_data)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>()))._type
|
||||
as *const _ as usize
|
||||
},
|
||||
4usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3),
|
||||
"::",
|
||||
stringify!(_type)
|
||||
)
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1() {
|
||||
assert_eq!(
|
||||
@@ -3808,6 +3880,19 @@ fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1() {
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1>()))._trapno as *const _
|
||||
as usize
|
||||
},
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1),
|
||||
"::",
|
||||
stringify!(_trapno)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1>()))._addr_lsb as *const _
|
||||
@@ -3847,6 +3932,19 @@ fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1() {
|
||||
stringify!(_addr_pkey)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1>()))._perf as *const _
|
||||
as usize
|
||||
},
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1),
|
||||
"::",
|
||||
stringify!(_perf)
|
||||
)
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout___sifields__bindgen_ty_5() {
|
||||
@@ -5873,7 +5971,7 @@ extern "C" {
|
||||
}
|
||||
extern "C" {
|
||||
pub fn select(
|
||||
__fd_count: ::std::os::raw::c_int,
|
||||
__max_fd_plus_one: ::std::os::raw::c_int,
|
||||
__read_fds: *mut fd_set,
|
||||
__write_fds: *mut fd_set,
|
||||
__exception_fds: *mut fd_set,
|
||||
@@ -5882,7 +5980,7 @@ extern "C" {
|
||||
}
|
||||
extern "C" {
|
||||
pub fn pselect(
|
||||
__fd_count: ::std::os::raw::c_int,
|
||||
__max_fd_plus_one: ::std::os::raw::c_int,
|
||||
__read_fds: *mut fd_set,
|
||||
__write_fds: *mut fd_set,
|
||||
__exception_fds: *mut fd_set,
|
||||
@@ -5892,7 +5990,7 @@ extern "C" {
|
||||
}
|
||||
extern "C" {
|
||||
pub fn pselect64(
|
||||
__fd_count: ::std::os::raw::c_int,
|
||||
__max_fd_plus_one: ::std::os::raw::c_int,
|
||||
__read_fds: *mut fd_set,
|
||||
__write_fds: *mut fd_set,
|
||||
__exception_fds: *mut fd_set,
|
||||
@@ -6253,12 +6351,15 @@ pub struct clone_args {
|
||||
pub stack: __u64,
|
||||
pub stack_size: __u64,
|
||||
pub tls: __u64,
|
||||
pub set_tid: __u64,
|
||||
pub set_tid_size: __u64,
|
||||
pub cgroup: __u64,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_clone_args() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<clone_args>(),
|
||||
64usize,
|
||||
88usize,
|
||||
concat!("Size of: ", stringify!(clone_args))
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -6346,6 +6447,36 @@ fn bindgen_test_layout_clone_args() {
|
||||
stringify!(tls)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<clone_args>())).set_tid as *const _ as usize },
|
||||
64usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(clone_args),
|
||||
"::",
|
||||
stringify!(set_tid)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<clone_args>())).set_tid_size as *const _ as usize },
|
||||
72usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(clone_args),
|
||||
"::",
|
||||
stringify!(set_tid_size)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<clone_args>())).cgroup as *const _ as usize },
|
||||
80usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(clone_args),
|
||||
"::",
|
||||
stringify!(cgroup)
|
||||
)
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -7559,6 +7690,10 @@ pub struct AInputEvent {
|
||||
}
|
||||
pub const AINPUT_EVENT_TYPE_KEY: ::std::os::raw::c_uint = 1;
|
||||
pub const AINPUT_EVENT_TYPE_MOTION: ::std::os::raw::c_uint = 2;
|
||||
pub const AINPUT_EVENT_TYPE_FOCUS: ::std::os::raw::c_uint = 3;
|
||||
pub const AINPUT_EVENT_TYPE_CAPTURE: ::std::os::raw::c_uint = 4;
|
||||
pub const AINPUT_EVENT_TYPE_DRAG: ::std::os::raw::c_uint = 5;
|
||||
pub const AINPUT_EVENT_TYPE_TOUCH_MODE: ::std::os::raw::c_uint = 6;
|
||||
pub type _bindgen_ty_12 = ::std::os::raw::c_uint;
|
||||
pub const AKEY_EVENT_ACTION_DOWN: ::std::os::raw::c_uint = 0;
|
||||
pub const AKEY_EVENT_ACTION_UP: ::std::os::raw::c_uint = 1;
|
||||
@@ -7659,7 +7794,13 @@ pub const AMOTION_EVENT_TOOL_TYPE_FINGER: ::std::os::raw::c_uint = 1;
|
||||
pub const AMOTION_EVENT_TOOL_TYPE_STYLUS: ::std::os::raw::c_uint = 2;
|
||||
pub const AMOTION_EVENT_TOOL_TYPE_MOUSE: ::std::os::raw::c_uint = 3;
|
||||
pub const AMOTION_EVENT_TOOL_TYPE_ERASER: ::std::os::raw::c_uint = 4;
|
||||
pub const AMOTION_EVENT_TOOL_TYPE_PALM: ::std::os::raw::c_uint = 5;
|
||||
pub type _bindgen_ty_20 = ::std::os::raw::c_uint;
|
||||
pub const AMotionClassification_AMOTION_EVENT_CLASSIFICATION_NONE: AMotionClassification = 0;
|
||||
pub const AMotionClassification_AMOTION_EVENT_CLASSIFICATION_AMBIGUOUS_GESTURE:
|
||||
AMotionClassification = 1;
|
||||
pub const AMotionClassification_AMOTION_EVENT_CLASSIFICATION_DEEP_PRESS: AMotionClassification = 2;
|
||||
pub type AMotionClassification = u32;
|
||||
pub const AINPUT_SOURCE_CLASS_MASK: ::std::os::raw::c_uint = 255;
|
||||
pub const AINPUT_SOURCE_CLASS_NONE: ::std::os::raw::c_uint = 0;
|
||||
pub const AINPUT_SOURCE_CLASS_BUTTON: ::std::os::raw::c_uint = 1;
|
||||
@@ -7681,6 +7822,8 @@ pub const AINPUT_SOURCE_MOUSE_RELATIVE: ::std::os::raw::c_uint = 131076;
|
||||
pub const AINPUT_SOURCE_TOUCHPAD: ::std::os::raw::c_uint = 1048584;
|
||||
pub const AINPUT_SOURCE_TOUCH_NAVIGATION: ::std::os::raw::c_uint = 2097152;
|
||||
pub const AINPUT_SOURCE_JOYSTICK: ::std::os::raw::c_uint = 16777232;
|
||||
pub const AINPUT_SOURCE_HDMI: ::std::os::raw::c_uint = 33554433;
|
||||
pub const AINPUT_SOURCE_SENSOR: ::std::os::raw::c_uint = 67108864;
|
||||
pub const AINPUT_SOURCE_ROTARY_ENCODER: ::std::os::raw::c_uint = 4194304;
|
||||
pub const AINPUT_SOURCE_ANY: ::std::os::raw::c_uint = 4294967040;
|
||||
pub type _bindgen_ty_22 = ::std::os::raw::c_uint;
|
||||
@@ -7707,6 +7850,9 @@ extern "C" {
|
||||
extern "C" {
|
||||
pub fn AInputEvent_getSource(event: *const AInputEvent) -> i32;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AInputEvent_release(event: *const AInputEvent);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AKeyEvent_getAction(key_event: *const AInputEvent) -> i32;
|
||||
}
|
||||
@@ -7731,6 +7877,9 @@ extern "C" {
|
||||
extern "C" {
|
||||
pub fn AKeyEvent_getEventTime(key_event: *const AInputEvent) -> i64;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AKeyEvent_fromJava(env: *mut JNIEnv, keyEvent: jobject) -> *const AInputEvent;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AMotionEvent_getAction(motion_event: *const AInputEvent) -> i32;
|
||||
}
|
||||
@@ -7927,6 +8076,15 @@ extern "C" {
|
||||
history_index: size_t,
|
||||
) -> f32;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AMotionEvent_getActionButton(motion_event: *const AInputEvent) -> i32;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AMotionEvent_getClassification(motion_event: *const AInputEvent) -> i32;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AMotionEvent_fromJava(env: *mut JNIEnv, motionEvent: jobject) -> *const AInputEvent;
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct imaxdiv_t {
|
||||
@@ -8001,11 +8159,52 @@ extern "C" {
|
||||
) -> uintmax_t;
|
||||
}
|
||||
pub const ADataSpace_ADATASPACE_UNKNOWN: ADataSpace = 0;
|
||||
pub const ADataSpace_STANDARD_MASK: ADataSpace = 4128768;
|
||||
pub const ADataSpace_STANDARD_UNSPECIFIED: ADataSpace = 0;
|
||||
pub const ADataSpace_STANDARD_BT709: ADataSpace = 65536;
|
||||
pub const ADataSpace_STANDARD_BT601_625: ADataSpace = 131072;
|
||||
pub const ADataSpace_STANDARD_BT601_625_UNADJUSTED: ADataSpace = 196608;
|
||||
pub const ADataSpace_STANDARD_BT601_525: ADataSpace = 262144;
|
||||
pub const ADataSpace_STANDARD_BT601_525_UNADJUSTED: ADataSpace = 327680;
|
||||
pub const ADataSpace_STANDARD_BT2020: ADataSpace = 393216;
|
||||
pub const ADataSpace_STANDARD_BT2020_CONSTANT_LUMINANCE: ADataSpace = 458752;
|
||||
pub const ADataSpace_STANDARD_BT470M: ADataSpace = 524288;
|
||||
pub const ADataSpace_STANDARD_FILM: ADataSpace = 589824;
|
||||
pub const ADataSpace_STANDARD_DCI_P3: ADataSpace = 655360;
|
||||
pub const ADataSpace_STANDARD_ADOBE_RGB: ADataSpace = 720896;
|
||||
pub const ADataSpace_TRANSFER_MASK: ADataSpace = 130023424;
|
||||
pub const ADataSpace_TRANSFER_UNSPECIFIED: ADataSpace = 0;
|
||||
pub const ADataSpace_TRANSFER_LINEAR: ADataSpace = 4194304;
|
||||
pub const ADataSpace_TRANSFER_SRGB: ADataSpace = 8388608;
|
||||
pub const ADataSpace_TRANSFER_SMPTE_170M: ADataSpace = 12582912;
|
||||
pub const ADataSpace_TRANSFER_GAMMA2_2: ADataSpace = 16777216;
|
||||
pub const ADataSpace_TRANSFER_GAMMA2_6: ADataSpace = 20971520;
|
||||
pub const ADataSpace_TRANSFER_GAMMA2_8: ADataSpace = 25165824;
|
||||
pub const ADataSpace_TRANSFER_ST2084: ADataSpace = 29360128;
|
||||
pub const ADataSpace_TRANSFER_HLG: ADataSpace = 33554432;
|
||||
pub const ADataSpace_RANGE_MASK: ADataSpace = 939524096;
|
||||
pub const ADataSpace_RANGE_UNSPECIFIED: ADataSpace = 0;
|
||||
pub const ADataSpace_RANGE_FULL: ADataSpace = 134217728;
|
||||
pub const ADataSpace_RANGE_LIMITED: ADataSpace = 268435456;
|
||||
pub const ADataSpace_RANGE_EXTENDED: ADataSpace = 402653184;
|
||||
pub const ADataSpace_ADATASPACE_SCRGB_LINEAR: ADataSpace = 406913024;
|
||||
pub const ADataSpace_ADATASPACE_SRGB: ADataSpace = 142671872;
|
||||
pub const ADataSpace_ADATASPACE_SCRGB: ADataSpace = 411107328;
|
||||
pub const ADataSpace_ADATASPACE_DISPLAY_P3: ADataSpace = 143261696;
|
||||
pub const ADataSpace_ADATASPACE_BT2020_PQ: ADataSpace = 163971072;
|
||||
pub const ADataSpace_ADATASPACE_BT2020_ITU_PQ: ADataSpace = 298188800;
|
||||
pub const ADataSpace_ADATASPACE_ADOBE_RGB: ADataSpace = 151715840;
|
||||
pub const ADataSpace_ADATASPACE_JFIF: ADataSpace = 146931712;
|
||||
pub const ADataSpace_ADATASPACE_BT601_625: ADataSpace = 281149440;
|
||||
pub const ADataSpace_ADATASPACE_BT601_525: ADataSpace = 281280512;
|
||||
pub const ADataSpace_ADATASPACE_BT2020: ADataSpace = 147193856;
|
||||
pub const ADataSpace_ADATASPACE_BT709: ADataSpace = 281083904;
|
||||
pub const ADataSpace_ADATASPACE_DCI_P3: ADataSpace = 155844608;
|
||||
pub const ADataSpace_ADATASPACE_SRGB_LINEAR: ADataSpace = 138477568;
|
||||
pub const ADataSpace_ADATASPACE_BT2020_HLG: ADataSpace = 168165376;
|
||||
pub const ADataSpace_ADATASPACE_BT2020_ITU_HLG: ADataSpace = 302383104;
|
||||
pub const ADataSpace_DEPTH: ADataSpace = 4096;
|
||||
pub const ADataSpace_DYNAMIC_DEPTH: ADataSpace = 4098;
|
||||
pub type ADataSpace = ::std::os::raw::c_uint;
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -8086,6 +8285,8 @@ pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT: AHard
|
||||
52;
|
||||
pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_S8_UINT: AHardwareBuffer_Format = 53;
|
||||
pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420: AHardwareBuffer_Format = 35;
|
||||
pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_YCbCr_P010: AHardwareBuffer_Format = 54;
|
||||
pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_R8_UNORM: AHardwareBuffer_Format = 56;
|
||||
pub type AHardwareBuffer_Format = ::std::os::raw::c_uint;
|
||||
pub const AHardwareBuffer_UsageFlags_AHARDWAREBUFFER_USAGE_CPU_READ_NEVER:
|
||||
AHardwareBuffer_UsageFlags = 0;
|
||||
@@ -8394,15 +8595,6 @@ extern "C" {
|
||||
outVirtualAddress: *mut *mut ::std::os::raw::c_void,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_lockPlanes(
|
||||
buffer: *mut AHardwareBuffer,
|
||||
usage: u64,
|
||||
fence: i32,
|
||||
rect: *const ARect,
|
||||
outPlanes: *mut AHardwareBuffer_Planes,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_unlock(
|
||||
buffer: *mut AHardwareBuffer,
|
||||
@@ -8421,6 +8613,15 @@ extern "C" {
|
||||
outBuffer: *mut *mut AHardwareBuffer,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_lockPlanes(
|
||||
buffer: *mut AHardwareBuffer,
|
||||
usage: u64,
|
||||
fence: i32,
|
||||
rect: *const ARect,
|
||||
outPlanes: *mut AHardwareBuffer_Planes,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_isSupported(desc: *const AHardwareBuffer_Desc) -> ::std::os::raw::c_int;
|
||||
}
|
||||
@@ -8435,6 +8636,12 @@ extern "C" {
|
||||
outBytesPerStride: *mut i32,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_getId(
|
||||
buffer: *const AHardwareBuffer,
|
||||
outId: *mut u64,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct ANativeActivity {
|
||||
pub callbacks: *mut ANativeActivityCallbacks,
|
||||
@@ -9362,6 +9569,12 @@ extern "C" {
|
||||
#[doc = " actions for the command before calling this function."]
|
||||
pub fn android_app_post_exec_cmd(android_app: *mut android_app, cmd: i8);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn android_app_attach_input_queue_looper(android_app: *mut android_app);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn android_app_detach_input_queue_looper(android_app: *mut android_app);
|
||||
}
|
||||
extern "C" {
|
||||
#[doc = " Dummy function that used to be used to prevent the linker from stripping app"]
|
||||
#[doc = " glue code. No longer necessary, since __attribute__((visibility(\"default\")))"]
|
||||
|
||||
@@ -21,10 +21,13 @@ pub const __ANDROID_API_O_MR1__: u32 = 27;
|
||||
pub const __ANDROID_API_P__: u32 = 28;
|
||||
pub const __ANDROID_API_Q__: u32 = 29;
|
||||
pub const __ANDROID_API_R__: u32 = 30;
|
||||
pub const __NDK_MAJOR__: u32 = 21;
|
||||
pub const __NDK_MINOR__: u32 = 1;
|
||||
pub const __ANDROID_API_S__: u32 = 31;
|
||||
pub const __ANDROID_API_T__: u32 = 33;
|
||||
pub const __ANDROID_NDK__: u32 = 1;
|
||||
pub const __NDK_MAJOR__: u32 = 25;
|
||||
pub const __NDK_MINOR__: u32 = 0;
|
||||
pub const __NDK_BETA__: u32 = 0;
|
||||
pub const __NDK_BUILD__: u32 = 6352462;
|
||||
pub const __NDK_BUILD__: u32 = 8775105;
|
||||
pub const __NDK_CANARY__: u32 = 0;
|
||||
pub const POLLIN: u32 = 1;
|
||||
pub const POLLPRI: u32 = 2;
|
||||
@@ -299,18 +302,20 @@ pub const SIGPWR: u32 = 30;
|
||||
pub const SIGSYS: u32 = 31;
|
||||
pub const SIGUNUSED: u32 = 31;
|
||||
pub const __SIGRTMIN: u32 = 32;
|
||||
pub const SA_RESTORER: u32 = 67108864;
|
||||
pub const MINSIGSTKSZ: u32 = 2048;
|
||||
pub const SIGSTKSZ: u32 = 8192;
|
||||
pub const SA_NOCLDSTOP: u32 = 1;
|
||||
pub const SA_NOCLDWAIT: u32 = 2;
|
||||
pub const SA_SIGINFO: u32 = 4;
|
||||
pub const SA_UNSUPPORTED: u32 = 1024;
|
||||
pub const SA_EXPOSE_TAGBITS: u32 = 2048;
|
||||
pub const SA_ONSTACK: u32 = 134217728;
|
||||
pub const SA_RESTART: u32 = 268435456;
|
||||
pub const SA_NODEFER: u32 = 1073741824;
|
||||
pub const SA_RESETHAND: u32 = 2147483648;
|
||||
pub const SA_NOMASK: u32 = 1073741824;
|
||||
pub const SA_ONESHOT: u32 = 2147483648;
|
||||
pub const SA_RESTORER: u32 = 67108864;
|
||||
pub const MINSIGSTKSZ: u32 = 2048;
|
||||
pub const SIGSTKSZ: u32 = 8192;
|
||||
pub const SIG_BLOCK: u32 = 0;
|
||||
pub const SIG_UNBLOCK: u32 = 1;
|
||||
pub const SIG_SETMASK: u32 = 2;
|
||||
@@ -360,7 +365,9 @@ pub const SEGV_PKUERR: u32 = 4;
|
||||
pub const SEGV_ACCADI: u32 = 5;
|
||||
pub const SEGV_ADIDERR: u32 = 6;
|
||||
pub const SEGV_ADIPERR: u32 = 7;
|
||||
pub const NSIGSEGV: u32 = 7;
|
||||
pub const SEGV_MTEAERR: u32 = 8;
|
||||
pub const SEGV_MTESERR: u32 = 9;
|
||||
pub const NSIGSEGV: u32 = 9;
|
||||
pub const BUS_ADRALN: u32 = 1;
|
||||
pub const BUS_ADRERR: u32 = 2;
|
||||
pub const BUS_OBJERR: u32 = 3;
|
||||
@@ -372,7 +379,8 @@ pub const TRAP_TRACE: u32 = 2;
|
||||
pub const TRAP_BRANCH: u32 = 3;
|
||||
pub const TRAP_HWBKPT: u32 = 4;
|
||||
pub const TRAP_UNK: u32 = 5;
|
||||
pub const NSIGTRAP: u32 = 5;
|
||||
pub const TRAP_PERF: u32 = 6;
|
||||
pub const NSIGTRAP: u32 = 6;
|
||||
pub const CLD_EXITED: u32 = 1;
|
||||
pub const CLD_KILLED: u32 = 2;
|
||||
pub const CLD_DUMPED: u32 = 3;
|
||||
@@ -388,7 +396,8 @@ pub const POLL_PRI: u32 = 5;
|
||||
pub const POLL_HUP: u32 = 6;
|
||||
pub const NSIGPOLL: u32 = 6;
|
||||
pub const SYS_SECCOMP: u32 = 1;
|
||||
pub const NSIGSYS: u32 = 1;
|
||||
pub const SYS_USER_DISPATCH: u32 = 2;
|
||||
pub const NSIGSYS: u32 = 2;
|
||||
pub const EMT_TAGOVF: u32 = 1;
|
||||
pub const NSIGEMT: u32 = 1;
|
||||
pub const SIGEV_SIGNAL: u32 = 0;
|
||||
@@ -433,6 +442,12 @@ pub const CLONE_NEWUSER: u32 = 268435456;
|
||||
pub const CLONE_NEWPID: u32 = 536870912;
|
||||
pub const CLONE_NEWNET: u32 = 1073741824;
|
||||
pub const CLONE_IO: u32 = 2147483648;
|
||||
pub const CLONE_CLEAR_SIGHAND: u64 = 4294967296;
|
||||
pub const CLONE_INTO_CGROUP: u64 = 8589934592;
|
||||
pub const CLONE_NEWTIME: u32 = 128;
|
||||
pub const CLONE_ARGS_SIZE_VER0: u32 = 64;
|
||||
pub const CLONE_ARGS_SIZE_VER1: u32 = 80;
|
||||
pub const CLONE_ARGS_SIZE_VER2: u32 = 88;
|
||||
pub const SCHED_NORMAL: u32 = 0;
|
||||
pub const SCHED_FIFO: u32 = 1;
|
||||
pub const SCHED_RR: u32 = 2;
|
||||
@@ -466,6 +481,9 @@ pub const PTHREAD_SCOPE_SYSTEM: u32 = 0;
|
||||
pub const PTHREAD_SCOPE_PROCESS: u32 = 1;
|
||||
pub const __GNUC_VA_LIST: u32 = 1;
|
||||
pub const AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT: u32 = 8;
|
||||
pub const true_: u32 = 1;
|
||||
pub const false_: u32 = 0;
|
||||
pub const __bool_true_false_are_defined: u32 = 1;
|
||||
pub const __PRI_64_prefix: &[u8; 2usize] = b"l\0";
|
||||
pub const __PRI_PTR_prefix: &[u8; 2usize] = b"l\0";
|
||||
pub const __PRI_FAST_prefix: &[u8; 2usize] = b"l\0";
|
||||
@@ -842,6 +860,7 @@ fn bindgen_test_layout___kernel_fsid_t() {
|
||||
}
|
||||
pub type __kernel_off_t = __kernel_long_t;
|
||||
pub type __kernel_loff_t = ::std::os::raw::c_longlong;
|
||||
pub type __kernel_old_time_t = __kernel_long_t;
|
||||
pub type __kernel_time_t = __kernel_long_t;
|
||||
pub type __kernel_time64_t = ::std::os::raw::c_longlong;
|
||||
pub type __kernel_clock_t = __kernel_long_t;
|
||||
@@ -3005,40 +3024,40 @@ fn bindgen_test_layout___kernel_itimerspec() {
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct __kernel_old_timeval {
|
||||
pub tv_sec: __kernel_long_t,
|
||||
pub tv_usec: __kernel_long_t,
|
||||
pub struct __kernel_old_timespec {
|
||||
pub tv_sec: __kernel_old_time_t,
|
||||
pub tv_nsec: ::std::os::raw::c_long,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout___kernel_old_timeval() {
|
||||
fn bindgen_test_layout___kernel_old_timespec() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<__kernel_old_timeval>(),
|
||||
::std::mem::size_of::<__kernel_old_timespec>(),
|
||||
16usize,
|
||||
concat!("Size of: ", stringify!(__kernel_old_timeval))
|
||||
concat!("Size of: ", stringify!(__kernel_old_timespec))
|
||||
);
|
||||
assert_eq!(
|
||||
::std::mem::align_of::<__kernel_old_timeval>(),
|
||||
::std::mem::align_of::<__kernel_old_timespec>(),
|
||||
8usize,
|
||||
concat!("Alignment of ", stringify!(__kernel_old_timeval))
|
||||
concat!("Alignment of ", stringify!(__kernel_old_timespec))
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<__kernel_old_timeval>())).tv_sec as *const _ as usize },
|
||||
unsafe { &(*(::std::ptr::null::<__kernel_old_timespec>())).tv_sec as *const _ as usize },
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__kernel_old_timeval),
|
||||
stringify!(__kernel_old_timespec),
|
||||
"::",
|
||||
stringify!(tv_sec)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<__kernel_old_timeval>())).tv_usec as *const _ as usize },
|
||||
unsafe { &(*(::std::ptr::null::<__kernel_old_timespec>())).tv_nsec as *const _ as usize },
|
||||
8usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__kernel_old_timeval),
|
||||
stringify!(__kernel_old_timespec),
|
||||
"::",
|
||||
stringify!(tv_usec)
|
||||
stringify!(tv_nsec)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -3084,7 +3103,7 @@ fn bindgen_test_layout___kernel_sock_timeval() {
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct timespec {
|
||||
pub tv_sec: __kernel_time_t,
|
||||
pub tv_sec: __kernel_old_time_t,
|
||||
pub tv_nsec: ::std::os::raw::c_long,
|
||||
}
|
||||
#[test]
|
||||
@@ -3123,7 +3142,7 @@ fn bindgen_test_layout_timespec() {
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct timeval {
|
||||
pub tv_sec: __kernel_time_t,
|
||||
pub tv_sec: __kernel_old_time_t,
|
||||
pub tv_usec: __kernel_suseconds_t,
|
||||
}
|
||||
#[test]
|
||||
@@ -3161,45 +3180,6 @@ fn bindgen_test_layout_timeval() {
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct timezone {
|
||||
pub tz_minuteswest: ::std::os::raw::c_int,
|
||||
pub tz_dsttime: ::std::os::raw::c_int,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_timezone() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<timezone>(),
|
||||
8usize,
|
||||
concat!("Size of: ", stringify!(timezone))
|
||||
);
|
||||
assert_eq!(
|
||||
::std::mem::align_of::<timezone>(),
|
||||
4usize,
|
||||
concat!("Alignment of ", stringify!(timezone))
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<timezone>())).tz_minuteswest as *const _ as usize },
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(timezone),
|
||||
"::",
|
||||
stringify!(tz_minuteswest)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<timezone>())).tz_dsttime as *const _ as usize },
|
||||
4usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(timezone),
|
||||
"::",
|
||||
stringify!(tz_dsttime)
|
||||
)
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct itimerspec {
|
||||
pub it_interval: timespec,
|
||||
pub it_value: timespec,
|
||||
@@ -3276,6 +3256,45 @@ fn bindgen_test_layout_itimerval() {
|
||||
)
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct timezone {
|
||||
pub tz_minuteswest: ::std::os::raw::c_int,
|
||||
pub tz_dsttime: ::std::os::raw::c_int,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_timezone() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<timezone>(),
|
||||
8usize,
|
||||
concat!("Size of: ", stringify!(timezone))
|
||||
);
|
||||
assert_eq!(
|
||||
::std::mem::align_of::<timezone>(),
|
||||
4usize,
|
||||
concat!("Alignment of ", stringify!(timezone))
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<timezone>())).tz_minuteswest as *const _ as usize },
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(timezone),
|
||||
"::",
|
||||
stringify!(tz_minuteswest)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<timezone>())).tz_dsttime as *const _ as usize },
|
||||
4usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(timezone),
|
||||
"::",
|
||||
stringify!(tz_dsttime)
|
||||
)
|
||||
);
|
||||
}
|
||||
pub type sigset_t = ::std::os::raw::c_ulong;
|
||||
pub type __signalfn_t = ::std::option::Option<unsafe extern "C" fn(arg1: ::std::os::raw::c_int)>;
|
||||
pub type __sighandler_t = __signalfn_t;
|
||||
@@ -3685,9 +3704,11 @@ pub struct __sifields__bindgen_ty_5 {
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub union __sifields__bindgen_ty_5__bindgen_ty_1 {
|
||||
pub _trapno: ::std::os::raw::c_int,
|
||||
pub _addr_lsb: ::std::os::raw::c_short,
|
||||
pub _addr_bnd: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1,
|
||||
pub _addr_pkey: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2,
|
||||
pub _perf: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3,
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -3805,6 +3826,57 @@ fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2() {
|
||||
)
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3 {
|
||||
pub _data: ::std::os::raw::c_ulong,
|
||||
pub _type: __u32,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>(),
|
||||
16usize,
|
||||
concat!(
|
||||
"Size of: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
::std::mem::align_of::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>(),
|
||||
8usize,
|
||||
concat!(
|
||||
"Alignment of ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>()))._data
|
||||
as *const _ as usize
|
||||
},
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3),
|
||||
"::",
|
||||
stringify!(_data)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>()))._type
|
||||
as *const _ as usize
|
||||
},
|
||||
8usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3),
|
||||
"::",
|
||||
stringify!(_type)
|
||||
)
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1() {
|
||||
assert_eq!(
|
||||
@@ -3823,6 +3895,19 @@ fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1() {
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1>()))._trapno as *const _
|
||||
as usize
|
||||
},
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1),
|
||||
"::",
|
||||
stringify!(_trapno)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1>()))._addr_lsb as *const _
|
||||
@@ -3862,6 +3947,19 @@ fn bindgen_test_layout___sifields__bindgen_ty_5__bindgen_ty_1() {
|
||||
stringify!(_addr_pkey)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
&(*(::std::ptr::null::<__sifields__bindgen_ty_5__bindgen_ty_1>()))._perf as *const _
|
||||
as usize
|
||||
},
|
||||
0usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(__sifields__bindgen_ty_5__bindgen_ty_1),
|
||||
"::",
|
||||
stringify!(_perf)
|
||||
)
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout___sifields__bindgen_ty_5() {
|
||||
@@ -5903,7 +6001,7 @@ extern "C" {
|
||||
}
|
||||
extern "C" {
|
||||
pub fn select(
|
||||
__fd_count: ::std::os::raw::c_int,
|
||||
__max_fd_plus_one: ::std::os::raw::c_int,
|
||||
__read_fds: *mut fd_set,
|
||||
__write_fds: *mut fd_set,
|
||||
__exception_fds: *mut fd_set,
|
||||
@@ -5912,7 +6010,7 @@ extern "C" {
|
||||
}
|
||||
extern "C" {
|
||||
pub fn pselect(
|
||||
__fd_count: ::std::os::raw::c_int,
|
||||
__max_fd_plus_one: ::std::os::raw::c_int,
|
||||
__read_fds: *mut fd_set,
|
||||
__write_fds: *mut fd_set,
|
||||
__exception_fds: *mut fd_set,
|
||||
@@ -5922,7 +6020,7 @@ extern "C" {
|
||||
}
|
||||
extern "C" {
|
||||
pub fn pselect64(
|
||||
__fd_count: ::std::os::raw::c_int,
|
||||
__max_fd_plus_one: ::std::os::raw::c_int,
|
||||
__read_fds: *mut fd_set,
|
||||
__write_fds: *mut fd_set,
|
||||
__exception_fds: *mut fd_set,
|
||||
@@ -6282,12 +6380,15 @@ pub struct clone_args {
|
||||
pub stack: __u64,
|
||||
pub stack_size: __u64,
|
||||
pub tls: __u64,
|
||||
pub set_tid: __u64,
|
||||
pub set_tid_size: __u64,
|
||||
pub cgroup: __u64,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_clone_args() {
|
||||
assert_eq!(
|
||||
::std::mem::size_of::<clone_args>(),
|
||||
64usize,
|
||||
88usize,
|
||||
concat!("Size of: ", stringify!(clone_args))
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -6375,6 +6476,36 @@ fn bindgen_test_layout_clone_args() {
|
||||
stringify!(tls)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<clone_args>())).set_tid as *const _ as usize },
|
||||
64usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(clone_args),
|
||||
"::",
|
||||
stringify!(set_tid)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<clone_args>())).set_tid_size as *const _ as usize },
|
||||
72usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(clone_args),
|
||||
"::",
|
||||
stringify!(set_tid_size)
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { &(*(::std::ptr::null::<clone_args>())).cgroup as *const _ as usize },
|
||||
80usize,
|
||||
concat!(
|
||||
"Offset of field: ",
|
||||
stringify!(clone_args),
|
||||
"::",
|
||||
stringify!(cgroup)
|
||||
)
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -7588,6 +7719,10 @@ pub struct AInputEvent {
|
||||
}
|
||||
pub const AINPUT_EVENT_TYPE_KEY: ::std::os::raw::c_uint = 1;
|
||||
pub const AINPUT_EVENT_TYPE_MOTION: ::std::os::raw::c_uint = 2;
|
||||
pub const AINPUT_EVENT_TYPE_FOCUS: ::std::os::raw::c_uint = 3;
|
||||
pub const AINPUT_EVENT_TYPE_CAPTURE: ::std::os::raw::c_uint = 4;
|
||||
pub const AINPUT_EVENT_TYPE_DRAG: ::std::os::raw::c_uint = 5;
|
||||
pub const AINPUT_EVENT_TYPE_TOUCH_MODE: ::std::os::raw::c_uint = 6;
|
||||
pub type _bindgen_ty_12 = ::std::os::raw::c_uint;
|
||||
pub const AKEY_EVENT_ACTION_DOWN: ::std::os::raw::c_uint = 0;
|
||||
pub const AKEY_EVENT_ACTION_UP: ::std::os::raw::c_uint = 1;
|
||||
@@ -7688,7 +7823,13 @@ pub const AMOTION_EVENT_TOOL_TYPE_FINGER: ::std::os::raw::c_uint = 1;
|
||||
pub const AMOTION_EVENT_TOOL_TYPE_STYLUS: ::std::os::raw::c_uint = 2;
|
||||
pub const AMOTION_EVENT_TOOL_TYPE_MOUSE: ::std::os::raw::c_uint = 3;
|
||||
pub const AMOTION_EVENT_TOOL_TYPE_ERASER: ::std::os::raw::c_uint = 4;
|
||||
pub const AMOTION_EVENT_TOOL_TYPE_PALM: ::std::os::raw::c_uint = 5;
|
||||
pub type _bindgen_ty_20 = ::std::os::raw::c_uint;
|
||||
pub const AMotionClassification_AMOTION_EVENT_CLASSIFICATION_NONE: AMotionClassification = 0;
|
||||
pub const AMotionClassification_AMOTION_EVENT_CLASSIFICATION_AMBIGUOUS_GESTURE:
|
||||
AMotionClassification = 1;
|
||||
pub const AMotionClassification_AMOTION_EVENT_CLASSIFICATION_DEEP_PRESS: AMotionClassification = 2;
|
||||
pub type AMotionClassification = u32;
|
||||
pub const AINPUT_SOURCE_CLASS_MASK: ::std::os::raw::c_uint = 255;
|
||||
pub const AINPUT_SOURCE_CLASS_NONE: ::std::os::raw::c_uint = 0;
|
||||
pub const AINPUT_SOURCE_CLASS_BUTTON: ::std::os::raw::c_uint = 1;
|
||||
@@ -7710,6 +7851,8 @@ pub const AINPUT_SOURCE_MOUSE_RELATIVE: ::std::os::raw::c_uint = 131076;
|
||||
pub const AINPUT_SOURCE_TOUCHPAD: ::std::os::raw::c_uint = 1048584;
|
||||
pub const AINPUT_SOURCE_TOUCH_NAVIGATION: ::std::os::raw::c_uint = 2097152;
|
||||
pub const AINPUT_SOURCE_JOYSTICK: ::std::os::raw::c_uint = 16777232;
|
||||
pub const AINPUT_SOURCE_HDMI: ::std::os::raw::c_uint = 33554433;
|
||||
pub const AINPUT_SOURCE_SENSOR: ::std::os::raw::c_uint = 67108864;
|
||||
pub const AINPUT_SOURCE_ROTARY_ENCODER: ::std::os::raw::c_uint = 4194304;
|
||||
pub const AINPUT_SOURCE_ANY: ::std::os::raw::c_uint = 4294967040;
|
||||
pub type _bindgen_ty_22 = ::std::os::raw::c_uint;
|
||||
@@ -7736,6 +7879,9 @@ extern "C" {
|
||||
extern "C" {
|
||||
pub fn AInputEvent_getSource(event: *const AInputEvent) -> i32;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AInputEvent_release(event: *const AInputEvent);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AKeyEvent_getAction(key_event: *const AInputEvent) -> i32;
|
||||
}
|
||||
@@ -7760,6 +7906,9 @@ extern "C" {
|
||||
extern "C" {
|
||||
pub fn AKeyEvent_getEventTime(key_event: *const AInputEvent) -> i64;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AKeyEvent_fromJava(env: *mut JNIEnv, keyEvent: jobject) -> *const AInputEvent;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AMotionEvent_getAction(motion_event: *const AInputEvent) -> i32;
|
||||
}
|
||||
@@ -7956,6 +8105,15 @@ extern "C" {
|
||||
history_index: size_t,
|
||||
) -> f32;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AMotionEvent_getActionButton(motion_event: *const AInputEvent) -> i32;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AMotionEvent_getClassification(motion_event: *const AInputEvent) -> i32;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AMotionEvent_fromJava(env: *mut JNIEnv, motionEvent: jobject) -> *const AInputEvent;
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct imaxdiv_t {
|
||||
@@ -8030,11 +8188,52 @@ extern "C" {
|
||||
) -> uintmax_t;
|
||||
}
|
||||
pub const ADataSpace_ADATASPACE_UNKNOWN: ADataSpace = 0;
|
||||
pub const ADataSpace_STANDARD_MASK: ADataSpace = 4128768;
|
||||
pub const ADataSpace_STANDARD_UNSPECIFIED: ADataSpace = 0;
|
||||
pub const ADataSpace_STANDARD_BT709: ADataSpace = 65536;
|
||||
pub const ADataSpace_STANDARD_BT601_625: ADataSpace = 131072;
|
||||
pub const ADataSpace_STANDARD_BT601_625_UNADJUSTED: ADataSpace = 196608;
|
||||
pub const ADataSpace_STANDARD_BT601_525: ADataSpace = 262144;
|
||||
pub const ADataSpace_STANDARD_BT601_525_UNADJUSTED: ADataSpace = 327680;
|
||||
pub const ADataSpace_STANDARD_BT2020: ADataSpace = 393216;
|
||||
pub const ADataSpace_STANDARD_BT2020_CONSTANT_LUMINANCE: ADataSpace = 458752;
|
||||
pub const ADataSpace_STANDARD_BT470M: ADataSpace = 524288;
|
||||
pub const ADataSpace_STANDARD_FILM: ADataSpace = 589824;
|
||||
pub const ADataSpace_STANDARD_DCI_P3: ADataSpace = 655360;
|
||||
pub const ADataSpace_STANDARD_ADOBE_RGB: ADataSpace = 720896;
|
||||
pub const ADataSpace_TRANSFER_MASK: ADataSpace = 130023424;
|
||||
pub const ADataSpace_TRANSFER_UNSPECIFIED: ADataSpace = 0;
|
||||
pub const ADataSpace_TRANSFER_LINEAR: ADataSpace = 4194304;
|
||||
pub const ADataSpace_TRANSFER_SRGB: ADataSpace = 8388608;
|
||||
pub const ADataSpace_TRANSFER_SMPTE_170M: ADataSpace = 12582912;
|
||||
pub const ADataSpace_TRANSFER_GAMMA2_2: ADataSpace = 16777216;
|
||||
pub const ADataSpace_TRANSFER_GAMMA2_6: ADataSpace = 20971520;
|
||||
pub const ADataSpace_TRANSFER_GAMMA2_8: ADataSpace = 25165824;
|
||||
pub const ADataSpace_TRANSFER_ST2084: ADataSpace = 29360128;
|
||||
pub const ADataSpace_TRANSFER_HLG: ADataSpace = 33554432;
|
||||
pub const ADataSpace_RANGE_MASK: ADataSpace = 939524096;
|
||||
pub const ADataSpace_RANGE_UNSPECIFIED: ADataSpace = 0;
|
||||
pub const ADataSpace_RANGE_FULL: ADataSpace = 134217728;
|
||||
pub const ADataSpace_RANGE_LIMITED: ADataSpace = 268435456;
|
||||
pub const ADataSpace_RANGE_EXTENDED: ADataSpace = 402653184;
|
||||
pub const ADataSpace_ADATASPACE_SCRGB_LINEAR: ADataSpace = 406913024;
|
||||
pub const ADataSpace_ADATASPACE_SRGB: ADataSpace = 142671872;
|
||||
pub const ADataSpace_ADATASPACE_SCRGB: ADataSpace = 411107328;
|
||||
pub const ADataSpace_ADATASPACE_DISPLAY_P3: ADataSpace = 143261696;
|
||||
pub const ADataSpace_ADATASPACE_BT2020_PQ: ADataSpace = 163971072;
|
||||
pub const ADataSpace_ADATASPACE_BT2020_ITU_PQ: ADataSpace = 298188800;
|
||||
pub const ADataSpace_ADATASPACE_ADOBE_RGB: ADataSpace = 151715840;
|
||||
pub const ADataSpace_ADATASPACE_JFIF: ADataSpace = 146931712;
|
||||
pub const ADataSpace_ADATASPACE_BT601_625: ADataSpace = 281149440;
|
||||
pub const ADataSpace_ADATASPACE_BT601_525: ADataSpace = 281280512;
|
||||
pub const ADataSpace_ADATASPACE_BT2020: ADataSpace = 147193856;
|
||||
pub const ADataSpace_ADATASPACE_BT709: ADataSpace = 281083904;
|
||||
pub const ADataSpace_ADATASPACE_DCI_P3: ADataSpace = 155844608;
|
||||
pub const ADataSpace_ADATASPACE_SRGB_LINEAR: ADataSpace = 138477568;
|
||||
pub const ADataSpace_ADATASPACE_BT2020_HLG: ADataSpace = 168165376;
|
||||
pub const ADataSpace_ADATASPACE_BT2020_ITU_HLG: ADataSpace = 302383104;
|
||||
pub const ADataSpace_DEPTH: ADataSpace = 4096;
|
||||
pub const ADataSpace_DYNAMIC_DEPTH: ADataSpace = 4098;
|
||||
pub type ADataSpace = ::std::os::raw::c_uint;
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -8115,6 +8314,8 @@ pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT: AHard
|
||||
52;
|
||||
pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_S8_UINT: AHardwareBuffer_Format = 53;
|
||||
pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420: AHardwareBuffer_Format = 35;
|
||||
pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_YCbCr_P010: AHardwareBuffer_Format = 54;
|
||||
pub const AHardwareBuffer_Format_AHARDWAREBUFFER_FORMAT_R8_UNORM: AHardwareBuffer_Format = 56;
|
||||
pub type AHardwareBuffer_Format = ::std::os::raw::c_uint;
|
||||
pub const AHardwareBuffer_UsageFlags_AHARDWAREBUFFER_USAGE_CPU_READ_NEVER:
|
||||
AHardwareBuffer_UsageFlags = 0;
|
||||
@@ -8423,15 +8624,6 @@ extern "C" {
|
||||
outVirtualAddress: *mut *mut ::std::os::raw::c_void,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_lockPlanes(
|
||||
buffer: *mut AHardwareBuffer,
|
||||
usage: u64,
|
||||
fence: i32,
|
||||
rect: *const ARect,
|
||||
outPlanes: *mut AHardwareBuffer_Planes,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_unlock(
|
||||
buffer: *mut AHardwareBuffer,
|
||||
@@ -8450,6 +8642,15 @@ extern "C" {
|
||||
outBuffer: *mut *mut AHardwareBuffer,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_lockPlanes(
|
||||
buffer: *mut AHardwareBuffer,
|
||||
usage: u64,
|
||||
fence: i32,
|
||||
rect: *const ARect,
|
||||
outPlanes: *mut AHardwareBuffer_Planes,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_isSupported(desc: *const AHardwareBuffer_Desc) -> ::std::os::raw::c_int;
|
||||
}
|
||||
@@ -8464,6 +8665,12 @@ extern "C" {
|
||||
outBytesPerStride: *mut i32,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn AHardwareBuffer_getId(
|
||||
buffer: *const AHardwareBuffer,
|
||||
outId: *mut u64,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct ANativeActivity {
|
||||
pub callbacks: *mut ANativeActivityCallbacks,
|
||||
@@ -9391,6 +9598,12 @@ extern "C" {
|
||||
#[doc = " actions for the command before calling this function."]
|
||||
pub fn android_app_post_exec_cmd(android_app: *mut android_app, cmd: i8);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn android_app_attach_input_queue_looper(android_app: *mut android_app);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn android_app_detach_input_queue_looper(android_app: *mut android_app);
|
||||
}
|
||||
extern "C" {
|
||||
#[doc = " Dummy function that used to be used to prevent the linker from stripping app"]
|
||||
#[doc = " glue code. No longer necessary, since __attribute__((visibility(\"default\")))"]
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
#![cfg(feature="native-activity")]
|
||||
#![cfg(any(feature = "native-activity", doc))]
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::ops::Deref;
|
||||
use std::os::raw;
|
||||
use std::ptr::NonNull;
|
||||
use std::sync::Arc;
|
||||
use std::sync::RwLock;
|
||||
use std::time::Duration;
|
||||
use std::{thread, ptr};
|
||||
use std::os::unix::prelude::*;
|
||||
use std::ptr::NonNull;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::time::Duration;
|
||||
use std::{ptr, thread};
|
||||
|
||||
use log::{Level, error, info, trace};
|
||||
use log::{error, info, trace, Level};
|
||||
|
||||
use ndk_sys::ALooper_wake;
|
||||
use ndk_sys::{ALooper, ALooper_pollAll};
|
||||
@@ -19,20 +19,27 @@ use ndk_sys::{ALooper, ALooper_pollAll};
|
||||
use ndk::asset::AssetManager;
|
||||
use ndk::configuration::Configuration;
|
||||
use ndk::input_queue::InputQueue;
|
||||
use ndk::looper::{FdEvent};
|
||||
use ndk::native_window::NativeWindow;
|
||||
|
||||
use crate::{MainEvent, Rect, PollEvent, AndroidApp, NativeWindowRef};
|
||||
|
||||
use crate::{util, AndroidApp, ConfigurationRef, MainEvent, PollEvent, Rect, WindowManagerFlags};
|
||||
|
||||
mod ffi;
|
||||
|
||||
pub mod input {
|
||||
pub use ndk::event::{
|
||||
InputEvent, Source, MetaState,
|
||||
MotionEvent, Pointer, MotionAction, Axis, ButtonState, EdgeFlags, MotionEventFlags,
|
||||
KeyEvent, KeyAction, Keycode, KeyEventFlags,
|
||||
Axis, ButtonState, EdgeFlags, KeyAction, KeyEvent, KeyEventFlags, Keycode, MetaState,
|
||||
MotionAction, MotionEvent, MotionEventFlags, Pointer, Source,
|
||||
};
|
||||
|
||||
// We use our own wrapper type for input events to have better consistency
|
||||
// with GameActivity and ensure the enum can be extended without needing a
|
||||
// semver bump
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum InputEvent {
|
||||
MotionEvent(self::MotionEvent),
|
||||
KeyEvent(self::KeyEvent),
|
||||
}
|
||||
}
|
||||
|
||||
// The only time it's safe to update the android_app->savedState pointer is
|
||||
@@ -45,12 +52,11 @@ pub struct StateSaver<'a> {
|
||||
|
||||
impl<'a> StateSaver<'a> {
|
||||
pub fn store(&self, state: &'a [u8]) {
|
||||
|
||||
// android_native_app_glue specifically expects savedState to have been allocated
|
||||
// via libc::malloc since it will automatically handle freeing the data once it
|
||||
// has been handed over to the Java Activity / main thread.
|
||||
unsafe {
|
||||
let app_ptr = self.app.ptr.as_ptr();
|
||||
let app_ptr = self.app.native_app.as_ptr();
|
||||
|
||||
// In case the application calls store() multiple times for some reason we
|
||||
// make sure to free any pre-existing state...
|
||||
@@ -75,7 +81,7 @@ impl<'a> StateSaver<'a> {
|
||||
}
|
||||
|
||||
(*app_ptr).savedState = buf;
|
||||
(*app_ptr).savedStateSize = state.len() as u64;
|
||||
(*app_ptr).savedStateSize = state.len() as _;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,9 +93,12 @@ pub struct StateLoader<'a> {
|
||||
impl<'a> StateLoader<'a> {
|
||||
pub fn load(&self) -> Option<Vec<u8>> {
|
||||
unsafe {
|
||||
let app_ptr = self.app.ptr.as_ptr();
|
||||
let app_ptr = self.app.native_app.as_ptr();
|
||||
if (*app_ptr).savedState != ptr::null_mut() && (*app_ptr).savedStateSize > 0 {
|
||||
let buf: &mut [u8] = std::slice::from_raw_parts_mut((*app_ptr).savedState.cast(), (*app_ptr).savedStateSize as usize);
|
||||
let buf: &mut [u8] = std::slice::from_raw_parts_mut(
|
||||
(*app_ptr).savedState.cast(),
|
||||
(*app_ptr).savedStateSize as usize,
|
||||
);
|
||||
let state = buf.to_vec();
|
||||
Some(state)
|
||||
} else {
|
||||
@@ -99,83 +108,99 @@ impl<'a> StateLoader<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AndroidAppWaker {
|
||||
// The looper pointer is owned by the android_app and effectively
|
||||
// has a 'static lifetime, and the ALooper_wake C API is thread
|
||||
// safe, so this can be cloned safely and is send + sync safe
|
||||
looper: NonNull<ALooper>
|
||||
looper: NonNull<ALooper>,
|
||||
}
|
||||
unsafe impl Send for AndroidAppWaker {}
|
||||
unsafe impl Sync for AndroidAppWaker {}
|
||||
|
||||
impl AndroidAppWaker {
|
||||
pub fn wake(&self) {
|
||||
unsafe { ALooper_wake(self.looper.as_ptr()); }
|
||||
unsafe {
|
||||
ALooper_wake(self.looper.as_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AndroidApp {
|
||||
pub(crate) unsafe fn from_ptr(ptr: NonNull<ffi::android_app>) -> AndroidApp {
|
||||
|
||||
// Note: we don't use from_ptr since we don't own the android_app.config
|
||||
// and need to keep in mind that the Drop handler is going to call
|
||||
// AConfiguration_delete()
|
||||
//
|
||||
// Whenever we get a ConfigChanged notification we synchronize this
|
||||
// config state with a deep copy.
|
||||
let config = Configuration::clone_from_ptr(NonNull::new_unchecked((*ptr.as_ptr()).config));
|
||||
|
||||
AndroidApp {
|
||||
inner: Arc::new(AndroidAppInner {
|
||||
ptr,
|
||||
config: RwLock::new(config),
|
||||
native_window: Default::default()
|
||||
})
|
||||
inner: Arc::new(RwLock::new(AndroidAppInner {
|
||||
native_app: NativeAppGlue { ptr },
|
||||
config: ConfigurationRef::new(config),
|
||||
native_window: Default::default(),
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct AndroidAppInner {
|
||||
struct NativeAppGlue {
|
||||
ptr: NonNull<ffi::android_app>,
|
||||
config: RwLock<Configuration>,
|
||||
}
|
||||
impl Deref for NativeAppGlue {
|
||||
type Target = NonNull<ffi::android_app>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.ptr
|
||||
}
|
||||
}
|
||||
unsafe impl Send for NativeAppGlue {}
|
||||
unsafe impl Sync for NativeAppGlue {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct AndroidAppInner {
|
||||
native_app: NativeAppGlue,
|
||||
config: ConfigurationRef,
|
||||
native_window: RwLock<Option<NativeWindow>>,
|
||||
}
|
||||
|
||||
impl AndroidAppInner {
|
||||
pub(crate) fn native_activity(&self) -> *const ndk_sys::ANativeActivity {
|
||||
unsafe {
|
||||
let app_ptr = self.ptr.as_ptr();
|
||||
let app_ptr = self.native_app.as_ptr();
|
||||
(*app_ptr).activity.cast()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn native_window<'a>(&self) -> Option<NativeWindowRef> {
|
||||
let guard = self.native_window.read().unwrap();
|
||||
if let Some(ref window) = *guard {
|
||||
Some(NativeWindowRef::new(window))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
pub fn native_window<'a>(&self) -> Option<NativeWindow> {
|
||||
self.native_window.read().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn poll_events<F>(&self, timeout: Option<Duration>, mut callback: F)
|
||||
where F: FnMut(PollEvent)
|
||||
where
|
||||
F: FnMut(PollEvent),
|
||||
{
|
||||
trace!("poll_events");
|
||||
|
||||
unsafe {
|
||||
let app_ptr = self.ptr;
|
||||
let native_app = &self.native_app;
|
||||
|
||||
let mut fd: i32 = 0;
|
||||
let mut events: i32 = 0;
|
||||
let mut source: *mut core::ffi::c_void = ptr::null_mut();
|
||||
|
||||
let timeout_milliseconds = if let Some(timeout) = timeout { timeout.as_millis() as i32 } else { -1 };
|
||||
let timeout_milliseconds = if let Some(timeout) = timeout {
|
||||
timeout.as_millis() as i32
|
||||
} else {
|
||||
-1
|
||||
};
|
||||
info!("Calling ALooper_pollAll, timeout = {timeout_milliseconds}");
|
||||
let id = ALooper_pollAll(timeout_milliseconds, &mut fd, &mut events, &mut source as *mut *mut core::ffi::c_void);
|
||||
let id = ALooper_pollAll(
|
||||
timeout_milliseconds,
|
||||
&mut fd,
|
||||
&mut events,
|
||||
&mut source as *mut *mut core::ffi::c_void,
|
||||
);
|
||||
info!("pollAll id = {id}");
|
||||
match id {
|
||||
ffi::ALOOPER_POLL_WAKE => {
|
||||
@@ -192,14 +217,9 @@ impl AndroidAppInner {
|
||||
callback(PollEvent::Timeout);
|
||||
}
|
||||
ffi::ALOOPER_POLL_ERROR => {
|
||||
trace!("ALooper_pollAll returned POLL_ERROR");
|
||||
callback(PollEvent::Error);
|
||||
|
||||
// Considering that this API is quite likely to be used in `android_main`
|
||||
// it's rather unergonomic to require the call to unwrap a Result for each
|
||||
// call to poll_events(). Alternatively we could maybe even just panic!()
|
||||
// here, while it's hard to imagine practically being able to recover
|
||||
//return Err(LooperError);
|
||||
// If we have an IO error with our pipe to the main Java thread that's surely
|
||||
// not something we can recover from
|
||||
panic!("ALooper_pollAll returned POLL_ERROR");
|
||||
}
|
||||
id if id >= 0 => {
|
||||
match id as u32 {
|
||||
@@ -207,7 +227,7 @@ impl AndroidAppInner {
|
||||
trace!("ALooper_pollAll returned ID_MAIN");
|
||||
let source: *mut ffi::android_poll_source = source.cast();
|
||||
if source != ptr::null_mut() {
|
||||
let cmd_i = ffi::android_app_read_cmd(app_ptr.as_ptr());
|
||||
let cmd_i = ffi::android_app_read_cmd(native_app.as_ptr());
|
||||
|
||||
let cmd = match cmd_i as u32 {
|
||||
// We don't forward info about the AInputQueue to apps since it's
|
||||
@@ -217,38 +237,58 @@ impl AndroidAppInner {
|
||||
|
||||
ffi::APP_CMD_INIT_WINDOW => Some(MainEvent::InitWindow {}),
|
||||
ffi::APP_CMD_TERM_WINDOW => Some(MainEvent::TerminateWindow {}),
|
||||
ffi::APP_CMD_WINDOW_RESIZED => Some(MainEvent::WindowResized {}),
|
||||
ffi::APP_CMD_WINDOW_REDRAW_NEEDED => Some(MainEvent::RedrawNeeded {}),
|
||||
ffi::APP_CMD_CONTENT_RECT_CHANGED => Some(MainEvent::ContentRectChanged),
|
||||
ffi::APP_CMD_WINDOW_RESIZED => {
|
||||
Some(MainEvent::WindowResized {})
|
||||
}
|
||||
ffi::APP_CMD_WINDOW_REDRAW_NEEDED => {
|
||||
Some(MainEvent::RedrawNeeded {})
|
||||
}
|
||||
ffi::APP_CMD_CONTENT_RECT_CHANGED => {
|
||||
Some(MainEvent::ContentRectChanged {})
|
||||
}
|
||||
ffi::APP_CMD_GAINED_FOCUS => Some(MainEvent::GainedFocus),
|
||||
ffi::APP_CMD_LOST_FOCUS => Some(MainEvent::LostFocus),
|
||||
ffi::APP_CMD_CONFIG_CHANGED => Some(MainEvent::ConfigChanged),
|
||||
ffi::APP_CMD_CONFIG_CHANGED => {
|
||||
Some(MainEvent::ConfigChanged {})
|
||||
}
|
||||
ffi::APP_CMD_LOW_MEMORY => Some(MainEvent::LowMemory),
|
||||
ffi::APP_CMD_START => Some(MainEvent::Start),
|
||||
ffi::APP_CMD_RESUME => Some(MainEvent::Resume { loader: StateLoader { app: &self } }),
|
||||
ffi::APP_CMD_SAVE_STATE => Some(MainEvent::SaveState { saver: StateSaver { app: &self } }),
|
||||
ffi::APP_CMD_RESUME => Some(MainEvent::Resume {
|
||||
loader: StateLoader { app: &self },
|
||||
}),
|
||||
ffi::APP_CMD_SAVE_STATE => Some(MainEvent::SaveState {
|
||||
saver: StateSaver { app: &self },
|
||||
}),
|
||||
ffi::APP_CMD_PAUSE => Some(MainEvent::Pause),
|
||||
ffi::APP_CMD_STOP => Some(MainEvent::Stop),
|
||||
ffi::APP_CMD_DESTROY => Some(MainEvent::Destroy),
|
||||
|
||||
//ffi::NativeAppGlueAppCmd_APP_CMD_WINDOW_INSETS_CHANGED => MainEvent::InsetsChanged {},
|
||||
_ => unreachable!()
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
trace!("Calling android_app_pre_exec_cmd({cmd_i})");
|
||||
ffi::android_app_pre_exec_cmd(app_ptr.as_ptr(), cmd_i);
|
||||
ffi::android_app_pre_exec_cmd(native_app.as_ptr(), cmd_i);
|
||||
|
||||
if let Some(cmd) = cmd {
|
||||
trace!("Read ID_MAIN command {cmd_i} = {cmd:?}");
|
||||
match cmd {
|
||||
MainEvent::ConfigChanged => {
|
||||
*self.config.write().unwrap() =
|
||||
Configuration::clone_from_ptr(NonNull::new_unchecked((*app_ptr.as_ptr()).config));
|
||||
MainEvent::ConfigChanged { .. } => {
|
||||
self.config.replace(Configuration::clone_from_ptr(
|
||||
NonNull::new_unchecked(
|
||||
(*native_app.as_ptr()).config,
|
||||
),
|
||||
));
|
||||
}
|
||||
MainEvent::InitWindow { .. } => {
|
||||
let win_ptr = (*app_ptr.as_ptr()).window;
|
||||
let win_ptr = (*native_app.as_ptr()).window;
|
||||
// It's important that we use ::clone_from_ptr() here
|
||||
// because NativeWindow has a Drop implementation that
|
||||
// will unconditionally _release() the native window
|
||||
*self.native_window.write().unwrap() =
|
||||
Some(NativeWindow::from_ptr(NonNull::new(win_ptr).unwrap()));
|
||||
Some(NativeWindow::clone_from_ptr(
|
||||
NonNull::new(win_ptr).unwrap(),
|
||||
));
|
||||
}
|
||||
MainEvent::TerminateWindow { .. } => {
|
||||
*self.native_window.write().unwrap() = None;
|
||||
@@ -261,32 +301,23 @@ impl AndroidAppInner {
|
||||
}
|
||||
|
||||
trace!("Calling android_app_post_exec_cmd({cmd_i})");
|
||||
ffi::android_app_post_exec_cmd(app_ptr.as_ptr(), cmd_i);
|
||||
ffi::android_app_post_exec_cmd(native_app.as_ptr(), cmd_i);
|
||||
} else {
|
||||
panic!("ALooper_pollAll returned ID_MAIN event with NULL android_poll_source!");
|
||||
}
|
||||
}
|
||||
ffi::LOOPER_ID_INPUT => {
|
||||
trace!("ALooper_pollAll returned ID_INPUT");
|
||||
// For now we don't forward notifications of input events specifically, we just
|
||||
// forward the notifications as a wake up, and assume the application main loop
|
||||
// will unconditionally check events for each iteration of it's event loop
|
||||
//
|
||||
// (Specifically notifying when input events are received would be inconsistent
|
||||
// with the current design of GameActivity input handling which we want to stay
|
||||
// compatible with))
|
||||
//
|
||||
// XXX: Actually it was a bad idea to emit a Wake for input since applications
|
||||
// are likely to _not_ consider that on its own a cause to redraw and it could
|
||||
// end up spamming enough wake ups to interfere with other events that would
|
||||
// trigger a redraw + input handling
|
||||
//callback(PollEvent::Wake);
|
||||
|
||||
// To avoid spamming the application with event loop iterations notifying them of
|
||||
// input events then we only send one `InputAvailable` per iteration of input
|
||||
// handling. We re-attach the looper when the application calls
|
||||
// `AndroidApp::input_events()`
|
||||
ffi::android_app_detach_input_queue_looper(native_app.as_ptr());
|
||||
callback(PollEvent::Main(MainEvent::InputAvailable))
|
||||
}
|
||||
_ => {
|
||||
let events = FdEvent::from_bits(events as u32)
|
||||
.expect(&format!("Spurious ALooper_pollAll event flags {:#04x}", events as u32));
|
||||
trace!("Custom ALooper event source: id = {id}, fd = {fd}, events = {events:?}, data = {source:?}");
|
||||
callback(PollEvent::FdEvent{ ident: id, fd: fd as RawFd, events, data: source });
|
||||
error!("Ignoring spurious ALooper event source: id = {id}, fd = {fd}, events = {events:?}, data = {source:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -301,18 +332,20 @@ impl AndroidAppInner {
|
||||
unsafe {
|
||||
// From the application's pov we assume the app_ptr and looper pointer
|
||||
// have static lifetimes and we can safely assume they are never NULL.
|
||||
let app_ptr = self.ptr.as_ptr();
|
||||
AndroidAppWaker { looper: NonNull::new_unchecked((*app_ptr).looper) }
|
||||
let app_ptr = self.native_app.as_ptr();
|
||||
AndroidAppWaker {
|
||||
looper: NonNull::new_unchecked((*app_ptr).looper),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn config(&self) -> Configuration {
|
||||
self.config.read().unwrap().clone()
|
||||
pub fn config(&self) -> ConfigurationRef {
|
||||
self.config.clone()
|
||||
}
|
||||
|
||||
pub fn content_rect(&self) -> Rect {
|
||||
unsafe {
|
||||
let app_ptr = self.ptr.as_ptr();
|
||||
let app_ptr = self.native_app.as_ptr();
|
||||
Rect {
|
||||
left: (*app_ptr).contentRect.left,
|
||||
right: (*app_ptr).contentRect.right,
|
||||
@@ -324,12 +357,54 @@ impl AndroidAppInner {
|
||||
|
||||
pub fn asset_manager(&self) -> AssetManager {
|
||||
unsafe {
|
||||
let app_ptr = self.ptr.as_ptr();
|
||||
let app_ptr = self.native_app.as_ptr();
|
||||
let am_ptr = NonNull::new_unchecked((*(*app_ptr).activity).assetManager);
|
||||
AssetManager::from_ptr(am_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_window_flags(
|
||||
&self,
|
||||
add_flags: WindowManagerFlags,
|
||||
remove_flags: WindowManagerFlags,
|
||||
) {
|
||||
let na = self.native_activity();
|
||||
let na_mut = na as *mut ndk_sys::ANativeActivity;
|
||||
unsafe {
|
||||
ffi::ANativeActivity_setWindowFlags(
|
||||
na_mut.cast(),
|
||||
add_flags.bits(),
|
||||
remove_flags.bits(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: move into a trait
|
||||
pub fn show_soft_input(&self, show_implicit: bool) {
|
||||
let na = self.native_activity();
|
||||
unsafe {
|
||||
let flags = if show_implicit {
|
||||
ffi::ANATIVEACTIVITY_SHOW_SOFT_INPUT_IMPLICIT
|
||||
} else {
|
||||
0
|
||||
};
|
||||
ffi::ANativeActivity_showSoftInput(na as *mut _, flags);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: move into a trait
|
||||
pub fn hide_soft_input(&self, hide_implicit_only: bool) {
|
||||
let na = self.native_activity();
|
||||
unsafe {
|
||||
let flags = if hide_implicit_only {
|
||||
ffi::ANATIVEACTIVITY_HIDE_SOFT_INPUT_IMPLICIT_ONLY
|
||||
} else {
|
||||
0
|
||||
};
|
||||
ffi::ANativeActivity_hideSoftInput(na as *mut _, flags);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enable_motion_axis(&self, _axis: input::Axis) {
|
||||
// NOP - The InputQueue API doesn't let us optimize which axis values are read
|
||||
}
|
||||
@@ -339,60 +414,67 @@ impl AndroidAppInner {
|
||||
}
|
||||
|
||||
pub fn input_events<'b, F>(&self, mut callback: F)
|
||||
where F: FnMut(&input::InputEvent)
|
||||
where
|
||||
F: FnMut(&input::InputEvent),
|
||||
{
|
||||
let queue = unsafe {
|
||||
let app_ptr = self.ptr.as_ptr();
|
||||
let app_ptr = self.native_app.as_ptr();
|
||||
if (*app_ptr).inputQueue == ptr::null_mut() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reattach the input queue to the looper so future input will again deliver an
|
||||
// `InputAvailable` event.
|
||||
ffi::android_app_attach_input_queue_looper(app_ptr);
|
||||
|
||||
let queue = NonNull::new_unchecked((*app_ptr).inputQueue);
|
||||
InputQueue::from_ptr(queue)
|
||||
};
|
||||
|
||||
info!("collect_events: START");
|
||||
while let Some(event) = queue.get_event() {
|
||||
info!("Got input event {event:?}");
|
||||
if let Some(event) = queue.pre_dispatch(event) {
|
||||
trace!("Pre dispatched input event {event:?}");
|
||||
|
||||
// Note: we basically ignore errors from get_event() currently. Looking
|
||||
// at the source code for Android's InputQueue, the only error that
|
||||
// can be returned here is 'WOULD_BLOCK', which we want to just treat as
|
||||
// meaning the queue is empty.
|
||||
//
|
||||
// ref: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/jni/android_view_InputQueue.cpp
|
||||
//
|
||||
while let Ok(Some(event)) = queue.get_event() {
|
||||
if let Some(ndk_event) = queue.pre_dispatch(event) {
|
||||
let event = match ndk_event {
|
||||
ndk::event::InputEvent::MotionEvent(e) => input::InputEvent::MotionEvent(e),
|
||||
ndk::event::InputEvent::KeyEvent(e) => input::InputEvent::KeyEvent(e),
|
||||
};
|
||||
callback(&event);
|
||||
|
||||
let ndk_event = match event {
|
||||
input::InputEvent::MotionEvent(e) => ndk::event::InputEvent::MotionEvent(e),
|
||||
input::InputEvent::KeyEvent(e) => ndk::event::InputEvent::KeyEvent(e),
|
||||
};
|
||||
|
||||
// Always report events as 'handled'. This means we won't get
|
||||
// so called 'fallback' events generated (such as converting trackball
|
||||
// events into emulated keypad events), but we could conceivably
|
||||
// implement similar emulation somewhere else in the stack if
|
||||
// necessary, and this will be more consistent with the GameActivity
|
||||
// input handling that doesn't do any kind of emulation.
|
||||
info!("Finishing input event {event:?}");
|
||||
queue.finish_event(event, true);
|
||||
queue.finish_event(ndk_event, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn try_get_path_from_ptr(path: *const u8) -> Option<std::path::PathBuf> {
|
||||
if path == ptr::null() { return None; }
|
||||
let cstr = unsafe {
|
||||
let cstr_slice = CStr::from_ptr(path);
|
||||
cstr_slice.to_str().ok()?
|
||||
};
|
||||
if cstr.len() == 0 { return None; }
|
||||
Some(std::path::PathBuf::from(cstr))
|
||||
}
|
||||
|
||||
pub fn internal_data_path(&self) -> Option<std::path::PathBuf> {
|
||||
let na = self.native_activity();
|
||||
unsafe { Self::try_get_path_from_ptr((*na).internalDataPath.cast()) }
|
||||
unsafe { util::try_get_path_from_ptr((*na).internalDataPath) }
|
||||
}
|
||||
|
||||
pub fn external_data_path(&self) -> Option<std::path::PathBuf> {
|
||||
let na = self.native_activity();
|
||||
unsafe { Self::try_get_path_from_ptr((*na).externalDataPath.cast()) }
|
||||
unsafe { util::try_get_path_from_ptr((*na).externalDataPath) }
|
||||
}
|
||||
|
||||
pub fn obb_path(&self) -> Option<std::path::PathBuf> {
|
||||
let na = self.native_activity();
|
||||
unsafe { Self::try_get_path_from_ptr((*na).obbPath.cast()) }
|
||||
unsafe { util::try_get_path_from_ptr((*na).obbPath) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,14 +502,14 @@ unsafe extern "C" fn ANativeActivity_onCreate(
|
||||
|
||||
fn android_log(level: Level, tag: &CStr, msg: &CStr) {
|
||||
let prio = match level {
|
||||
Level::Error => ndk_sys::android_LogPriority_ANDROID_LOG_ERROR,
|
||||
Level::Warn => ndk_sys::android_LogPriority_ANDROID_LOG_WARN,
|
||||
Level::Info => ndk_sys::android_LogPriority_ANDROID_LOG_INFO,
|
||||
Level::Debug => ndk_sys::android_LogPriority_ANDROID_LOG_DEBUG,
|
||||
Level::Trace => ndk_sys::android_LogPriority_ANDROID_LOG_VERBOSE,
|
||||
Level::Error => ndk_sys::android_LogPriority::ANDROID_LOG_ERROR,
|
||||
Level::Warn => ndk_sys::android_LogPriority::ANDROID_LOG_WARN,
|
||||
Level::Info => ndk_sys::android_LogPriority::ANDROID_LOG_INFO,
|
||||
Level::Debug => ndk_sys::android_LogPriority::ANDROID_LOG_DEBUG,
|
||||
Level::Trace => ndk_sys::android_LogPriority::ANDROID_LOG_VERBOSE,
|
||||
};
|
||||
unsafe {
|
||||
ndk_sys::__android_log_write(prio as raw::c_int, tag.as_ptr(), msg.as_ptr());
|
||||
ndk_sys::__android_log_write(prio.0 as raw::c_int, tag.as_ptr(), msg.as_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,7 +522,6 @@ extern "Rust" {
|
||||
// by android_native_app_glue.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn _rust_glue_entry(app: *mut ffi::android_app) {
|
||||
|
||||
// Maybe make this stdout/stderr redirection an optional / opt-in feature?...
|
||||
let mut logpipe: [RawFd; 2] = Default::default();
|
||||
libc::pipe(logpipe.as_mut_ptr());
|
||||
@@ -496,4 +577,4 @@ pub unsafe extern "C" fn _rust_glue_entry(app: *mut ffi::android_app) {
|
||||
}
|
||||
|
||||
ndk_context::release_android_context();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
use std::{ffi::CStr, os::raw::c_char, ptr};
|
||||
|
||||
pub fn try_get_path_from_ptr(path: *const c_char) -> Option<std::path::PathBuf> {
|
||||
if path == ptr::null() {
|
||||
return None;
|
||||
}
|
||||
let cstr = unsafe {
|
||||
let cstr_slice = CStr::from_ptr(path.cast());
|
||||
cstr_slice.to_str().ok()?
|
||||
};
|
||||
if cstr.len() == 0 {
|
||||
return None;
|
||||
}
|
||||
Some(std::path::PathBuf::from(cstr))
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
*.so
|
||||
|
||||
# Added by cargo
|
||||
|
||||
/target
|
||||
Cargo.lock
|
||||
@@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="11" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="GRADLE" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "agdk-cpal"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
android_logger = "0.11.0"
|
||||
android-activity = { path="../../android-activity", features = ["game-activity"] }
|
||||
cpal = "0.14"
|
||||
atomic_float = "0.1"
|
||||
anyhow = "1"
|
||||
|
||||
[lib]
|
||||
name="main"
|
||||
crate_type=["cdylib"]
|
||||
@@ -0,0 +1,16 @@
|
||||
This is a minimal test application based on `GameActivity` that just
|
||||
runs a mainloop based on android_activity::poll_events() and plays a
|
||||
sine wave audio test using the Cpal audio library.
|
||||
|
||||
```
|
||||
export ANDROID_NDK_HOME="path/to/ndk"
|
||||
export ANDROID_HOME="path/to/sdk"
|
||||
|
||||
rustup target add aarch64-linux-android
|
||||
cargo install cargo-ndk
|
||||
|
||||
cargo ndk -t arm64-v8a -o app/src/main/jniLibs/ build
|
||||
./gradlew build
|
||||
./gradlew installDebug
|
||||
adb shell am start -n co.realfit.agdkcpal/.MainActivity
|
||||
```
|
||||
@@ -0,0 +1 @@
|
||||
/build
|
||||
@@ -0,0 +1,61 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk 31
|
||||
|
||||
defaultConfig {
|
||||
applicationId "co.realfit.agdkcpal"
|
||||
minSdk 28
|
||||
targetSdk 31
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
debug {
|
||||
minifyEnabled false
|
||||
//packagingOptions {
|
||||
// doNotStrip '**/*.so'
|
||||
//}
|
||||
//debuggable true
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
implementation 'com.google.android.material:material:1.5.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
|
||||
// To use the Android Frame Pacing library
|
||||
//implementation "androidx.games:games-frame-pacing:1.9.1"
|
||||
|
||||
// To use the Android Performance Tuner
|
||||
//implementation "androidx.games:games-performance-tuner:1.5.0"
|
||||
|
||||
// To use the Games Activity library
|
||||
implementation "androidx.games:games-activity:1.1.0"
|
||||
|
||||
// To use the Games Controller Library
|
||||
//implementation "androidx.games:games-controller:1.1.0"
|
||||
|
||||
// To use the Games Text Input Library
|
||||
//implementation "androidx.games:games-text-input:1.1.0"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="co.realfit.agdkcpal">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="AGDK Cpal"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.RustTemplate">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data android:name="android.app.lib_name" android:value="main" />
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,70 @@
|
||||
package co.realfit.agdkcpal;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
import androidx.core.view.WindowInsetsControllerCompat;
|
||||
|
||||
import com.google.androidgamesdk.GameActivity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build.VERSION;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
public class MainActivity extends GameActivity {
|
||||
|
||||
static {
|
||||
// Load the STL first to workaround issues on old Android versions:
|
||||
// "if your app targets a version of Android earlier than Android 4.3
|
||||
// (Android API level 18),
|
||||
// and you use libc++_shared.so, you must load the shared library before any other
|
||||
// library that depends on it."
|
||||
// See https://developer.android.com/ndk/guides/cpp-support#shared_runtimes
|
||||
//System.loadLibrary("c++_shared");
|
||||
|
||||
// Load the native library.
|
||||
// The name "android-game" depends on your CMake configuration, must be
|
||||
// consistent here and inside AndroidManifect.xml
|
||||
System.loadLibrary("main");
|
||||
}
|
||||
|
||||
private void hideSystemUI() {
|
||||
// This will put the game behind any cutouts and waterfalls on devices which have
|
||||
// them, so the corresponding insets will be non-zero.
|
||||
if (VERSION.SDK_INT >= VERSION_CODES.P) {
|
||||
getWindow().getAttributes().layoutInDisplayCutoutMode
|
||||
= WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
|
||||
}
|
||||
// From API 30 onwards, this is the recommended way to hide the system UI, rather than
|
||||
// using View.setSystemUiVisibility.
|
||||
View decorView = getWindow().getDecorView();
|
||||
WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(getWindow(),
|
||||
decorView);
|
||||
controller.hide(WindowInsetsCompat.Type.systemBars());
|
||||
controller.hide(WindowInsetsCompat.Type.displayCutout());
|
||||
controller.setSystemBarsBehavior(
|
||||
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
// When true, the app will fit inside any system UI windows.
|
||||
// When false, we render behind any system UI windows.
|
||||
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
|
||||
hideSystemUI();
|
||||
// You can set IME fields here or in native code using GameActivity_setImeEditorInfoFields.
|
||||
// We set the fields in native_engine.cpp.
|
||||
// super.setImeEditorInfoFields(InputType.TYPE_CLASS_TEXT,
|
||||
// IME_ACTION_NONE, IME_FLAG_NO_FULLSCREEN );
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
public boolean isGooglePlayGames() {
|
||||
PackageManager pm = getPackageManager();
|
||||
return pm.hasSystemFeature("com.google.android.play.feature.HPE_EXPERIENCE");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
@@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hello World!"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 982 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
@@ -0,0 +1,16 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.RustTemplate" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_200</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/black</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_200</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="purple_200">#FFBB86FC</color>
|
||||
<color name="purple_500">#FF6200EE</color>
|
||||
<color name="purple_700">#FF3700B3</color>
|
||||
<color name="teal_200">#FF03DAC5</color>
|
||||
<color name="teal_700">#FF018786</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
</resources>
|
||||
@@ -0,0 +1,16 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.RustTemplate" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_500</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/white</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_700</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
||||
@@ -0,0 +1,10 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
id 'com.android.application' version '7.1.2' apply false
|
||||
id 'com.android.library' version '7.1.2' apply false
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Project-wide Gradle settings.
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||
# Android operating system, and which are packaged with your app"s APK
|
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
||||
# Enables namespacing of each library's R class so that its R class includes only the
|
||||
# resources declared in the library itself and none from the library's dependencies,
|
||||
# thereby reducing the size of the R class for that library
|
||||
android.nonTransitiveRClass=true
|
||||
@@ -0,0 +1,6 @@
|
||||
#Mon May 02 15:39:12 BST 2022
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
@@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
@@ -0,0 +1,89 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -0,0 +1,16 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
//rootProject.name = "Rust Template"
|
||||
include ':app'
|
||||
@@ -0,0 +1,142 @@
|
||||
use android_activity::{AndroidApp, MainEvent, PollEvent};
|
||||
use log::info;
|
||||
|
||||
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
|
||||
extern crate cpal;
|
||||
|
||||
fn write_data<T>(output: &mut [T], channels: usize, next_sample: &mut dyn FnMut() -> f32)
|
||||
where
|
||||
T: cpal::Sample,
|
||||
{
|
||||
for frame in output.chunks_mut(channels) {
|
||||
let value: T = cpal::Sample::from::<f32>(&next_sample());
|
||||
for sample in frame.iter_mut() {
|
||||
*sample = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn make_audio_stream<T>(
|
||||
device: &cpal::Device,
|
||||
config: &cpal::StreamConfig,
|
||||
) -> Result<cpal::Stream, anyhow::Error>
|
||||
where
|
||||
T: cpal::Sample,
|
||||
{
|
||||
let sample_rate = config.sample_rate.0 as f32;
|
||||
let channels = config.channels as usize;
|
||||
|
||||
// Produce a sinusoid of maximum amplitude.
|
||||
let mut sample_clock = 0f32;
|
||||
let mut next_value = move || {
|
||||
sample_clock = (sample_clock + 1.0) % sample_rate;
|
||||
(sample_clock * 440.0 * 2.0 * std::f32::consts::PI / sample_rate).sin()
|
||||
};
|
||||
|
||||
let err_fn = |err| eprintln!("an error occurred on stream: {}", err);
|
||||
|
||||
let stream = device.build_output_stream(
|
||||
config,
|
||||
move |data: &mut [T], _: &cpal::OutputCallbackInfo| {
|
||||
write_data(data, channels, &mut next_value)
|
||||
},
|
||||
err_fn,
|
||||
)?;
|
||||
Ok(stream)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
fn android_main(app: AndroidApp) {
|
||||
android_logger::init_once(android_logger::Config::default().with_min_level(log::Level::Info));
|
||||
|
||||
let mut quit = false;
|
||||
let mut redraw_pending = true;
|
||||
let mut render_state: Option<()> = Default::default();
|
||||
|
||||
let host = cpal::default_host();
|
||||
|
||||
let device = host
|
||||
.default_output_device()
|
||||
.expect("failed to find output device");
|
||||
|
||||
let config = device.default_output_config().unwrap();
|
||||
|
||||
let stream = match config.sample_format() {
|
||||
cpal::SampleFormat::F32 => make_audio_stream::<f32>(&device, &config.into()).unwrap(),
|
||||
cpal::SampleFormat::I16 => make_audio_stream::<i16>(&device, &config.into()).unwrap(),
|
||||
cpal::SampleFormat::U16 => make_audio_stream::<u16>(&device, &config.into()).unwrap(),
|
||||
};
|
||||
|
||||
while !quit {
|
||||
app.poll_events(
|
||||
Some(std::time::Duration::from_millis(500)), /* timeout */
|
||||
|event| {
|
||||
match event {
|
||||
PollEvent::Wake => {
|
||||
info!("Early wake up");
|
||||
}
|
||||
PollEvent::Timeout => {
|
||||
info!("Timed out");
|
||||
// Real app would probably rely on vblank sync via graphics API...
|
||||
redraw_pending = true;
|
||||
}
|
||||
PollEvent::Main(main_event) => {
|
||||
info!("Main event: {:?}", main_event);
|
||||
match main_event {
|
||||
MainEvent::SaveState { saver, .. } => {
|
||||
saver.store("foo://bar".as_bytes());
|
||||
}
|
||||
MainEvent::Pause => {
|
||||
if let Err(err) = stream.pause() {
|
||||
log::error!("Failed to pause audio playback: {err}");
|
||||
}
|
||||
}
|
||||
MainEvent::Resume { loader, .. } => {
|
||||
if let Some(state) = loader.load() {
|
||||
if let Ok(uri) = String::from_utf8(state) {
|
||||
info!("Resumed with saved state = {uri:#?}");
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(err) = stream.play() {
|
||||
log::error!("Failed to start audio playback: {err}");
|
||||
}
|
||||
}
|
||||
MainEvent::InitWindow { .. } => {
|
||||
render_state = Some(());
|
||||
redraw_pending = true;
|
||||
}
|
||||
MainEvent::TerminateWindow { .. } => {
|
||||
render_state = None;
|
||||
}
|
||||
MainEvent::WindowResized { .. } => {
|
||||
redraw_pending = true;
|
||||
}
|
||||
MainEvent::RedrawNeeded { .. } => {
|
||||
redraw_pending = true;
|
||||
}
|
||||
MainEvent::LowMemory => {}
|
||||
|
||||
MainEvent::Destroy => quit = true,
|
||||
_ => { /* ... */ }
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if redraw_pending {
|
||||
if let Some(_rs) = render_state {
|
||||
redraw_pending = false;
|
||||
|
||||
// Handle input
|
||||
app.input_events(|event| {
|
||||
info!("Input Event: {event:?}");
|
||||
});
|
||||
|
||||
info!("Render...");
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
*.so
|
||||
|
||||
|
||||
# Added by cargo
|
||||
|
||||
/target
|
||||
@@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="11" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="GRADLE" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DesignSurface">
|
||||
<option name="filePathToZoomLevelMap">
|
||||
<map>
|
||||
<entry key="..\:/Users/Robert/src/agdk-rust/examples/agdk-winit-wgpu/app/src/main/res/layout/activity_main.xml" value="0.5546875" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,66 @@
|
||||
[package]
|
||||
name = "agdk-eframe"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
resolver = "2"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
winit = "0.27.2"
|
||||
wgpu = "0.13.0"
|
||||
pollster = "0.2"
|
||||
egui = "0.19"
|
||||
eframe = { version = "0.19", features = [ "wgpu" ] }
|
||||
egui_demo_lib = "0.19"
|
||||
|
||||
[target.'cfg(not(target_os = "android"))'.dependencies]
|
||||
env_logger = "0.9"
|
||||
|
||||
[target.'cfg(target_os = "android")'.dependencies]
|
||||
android_logger = "0.11.0"
|
||||
android-activity = { version = "0.3", features = [ "game-activity" ] }
|
||||
|
||||
[patch.crates-io]
|
||||
|
||||
# This branch of Winit has an updated Android backend based on android-activity
|
||||
# Note: The winit branches are current misnamed:
|
||||
# - "android-activity" is based on Winit 0.27 (required for Egui compatibility)
|
||||
# - "android-activity-0.27" is based on Winit master
|
||||
# The -0.27 branch is currently associated with a pull request so we'll just
|
||||
# stick with these names for now
|
||||
winit = { git = "https://github.com/rib/winit", branch = "android-activity" }
|
||||
#winit = { path = "../../../winit" }
|
||||
|
||||
# Note:
|
||||
# Since android-activity is responsible for invoking the `android_main`
|
||||
# entrypoint for a native Rust application there can only be a single
|
||||
# implementation of the crate linked with the application.
|
||||
#
|
||||
# Since Winit also depends on android-activity (version = "0.2") but we'd like
|
||||
# to build against the local version of android-activity in this repo then we
|
||||
# use a [patch] to ensure we only end up with a single implementation.
|
||||
android-activity = { path = "../../android-activity" }
|
||||
|
||||
# Egui 0.19 is missing some fixes for Android so we need to build against
|
||||
# git master for now
|
||||
egui = { git = "https://github.com/emilk/egui" }
|
||||
eframe = { git = "https://github.com/emilk/egui" }
|
||||
egui_demo_lib = { git = "https://github.com/emilk/egui" }
|
||||
#egui = { path = "../../../egui/crates/egui" }
|
||||
#eframe = { path = "../../../egui/crates/eframe" }
|
||||
#egui_demo_lib = { path = "../../../egui/crates/egui_demo_lib" }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
desktop = []
|
||||
|
||||
[lib]
|
||||
name="main"
|
||||
crate_type=["cdylib"]
|
||||
|
||||
[[bin]]
|
||||
path="src/lib.rs"
|
||||
name="agdk-eframe"
|
||||
required-features = [ "desktop" ]
|
||||
@@ -0,0 +1,17 @@
|
||||
This tests using `GameActivity` with egui, winit and wgpu.
|
||||
|
||||
This is based on a re-worked winit backend here:
|
||||
https://github.com/rib/winit/tree/android-activity
|
||||
|
||||
```
|
||||
export ANDROID_NDK_HOME="path/to/ndk"
|
||||
export ANDROID_HOME="path/to/sdk"
|
||||
|
||||
rustup target add aarch64-linux-android
|
||||
cargo install cargo-ndk
|
||||
|
||||
cargo ndk -t arm64-v8a -o app/src/main/jniLibs/ build
|
||||
./gradlew build
|
||||
./gradlew installDebug
|
||||
adb shell am start -n co.realfit.agdkeframe/.MainActivity
|
||||
```
|
||||
@@ -0,0 +1 @@
|
||||
/build
|
||||
@@ -0,0 +1,61 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk 31
|
||||
|
||||
defaultConfig {
|
||||
applicationId "co.realfit.agdkeframe"
|
||||
minSdk 28
|
||||
targetSdk 31
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
debug {
|
||||
minifyEnabled false
|
||||
//packagingOptions {
|
||||
// doNotStrip '**/*.so'
|
||||
//}
|
||||
//debuggable true
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
implementation 'com.google.android.material:material:1.5.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
|
||||
// To use the Android Frame Pacing library
|
||||
//implementation "androidx.games:games-frame-pacing:1.9.1"
|
||||
|
||||
// To use the Android Performance Tuner
|
||||
//implementation "androidx.games:games-performance-tuner:1.5.0"
|
||||
|
||||
// To use the Games Activity library
|
||||
implementation "androidx.games:games-activity:1.1.0"
|
||||
|
||||
// To use the Games Controller Library
|
||||
//implementation "androidx.games:games-controller:1.1.0"
|
||||
|
||||
// To use the Games Text Input Library
|
||||
//implementation "androidx.games:games-text-input:1.1.0"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="co.realfit.agdkeframe">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="AGDK EFrame"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.RustTemplate">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data android:name="android.app.lib_name" android:value="main" />
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,70 @@
|
||||
package co.realfit.agdkeframe;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
import androidx.core.view.WindowInsetsControllerCompat;
|
||||
|
||||
import com.google.androidgamesdk.GameActivity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build.VERSION;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
public class MainActivity extends GameActivity {
|
||||
|
||||
static {
|
||||
// Load the STL first to workaround issues on old Android versions:
|
||||
// "if your app targets a version of Android earlier than Android 4.3
|
||||
// (Android API level 18),
|
||||
// and you use libc++_shared.so, you must load the shared library before any other
|
||||
// library that depends on it."
|
||||
// See https://developer.android.com/ndk/guides/cpp-support#shared_runtimes
|
||||
//System.loadLibrary("c++_shared");
|
||||
|
||||
// Load the native library.
|
||||
// The name "android-game" depends on your CMake configuration, must be
|
||||
// consistent here and inside AndroidManifect.xml
|
||||
System.loadLibrary("main");
|
||||
}
|
||||
|
||||
private void hideSystemUI() {
|
||||
// This will put the game behind any cutouts and waterfalls on devices which have
|
||||
// them, so the corresponding insets will be non-zero.
|
||||
if (VERSION.SDK_INT >= VERSION_CODES.P) {
|
||||
getWindow().getAttributes().layoutInDisplayCutoutMode
|
||||
= WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
|
||||
}
|
||||
// From API 30 onwards, this is the recommended way to hide the system UI, rather than
|
||||
// using View.setSystemUiVisibility.
|
||||
View decorView = getWindow().getDecorView();
|
||||
WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(getWindow(),
|
||||
decorView);
|
||||
controller.hide(WindowInsetsCompat.Type.systemBars());
|
||||
controller.hide(WindowInsetsCompat.Type.displayCutout());
|
||||
controller.setSystemBarsBehavior(
|
||||
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
// When true, the app will fit inside any system UI windows.
|
||||
// When false, we render behind any system UI windows.
|
||||
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
|
||||
hideSystemUI();
|
||||
// You can set IME fields here or in native code using GameActivity_setImeEditorInfoFields.
|
||||
// We set the fields in native_engine.cpp.
|
||||
// super.setImeEditorInfoFields(InputType.TYPE_CLASS_TEXT,
|
||||
// IME_ACTION_NONE, IME_FLAG_NO_FULLSCREEN );
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
public boolean isGooglePlayGames() {
|
||||
PackageManager pm = getPackageManager();
|
||||
return pm.hasSystemFeature("com.google.android.play.feature.HPE_EXPERIENCE");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
@@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hello World!"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 982 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
@@ -0,0 +1,16 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.RustTemplate" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_200</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/black</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_200</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="purple_200">#FFBB86FC</color>
|
||||
<color name="purple_500">#FF6200EE</color>
|
||||
<color name="purple_700">#FF3700B3</color>
|
||||
<color name="teal_200">#FF03DAC5</color>
|
||||
<color name="teal_700">#FF018786</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
</resources>
|
||||
@@ -0,0 +1,16 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.RustTemplate" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_500</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/white</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_700</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
||||
@@ -0,0 +1,10 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
id 'com.android.application' version '7.1.2' apply false
|
||||
id 'com.android.library' version '7.1.2' apply false
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Project-wide Gradle settings.
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||
# Android operating system, and which are packaged with your app"s APK
|
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
||||
# Enables namespacing of each library's R class so that its R class includes only the
|
||||
# resources declared in the library itself and none from the library's dependencies,
|
||||
# thereby reducing the size of the R class for that library
|
||||
android.nonTransitiveRClass=true
|
||||