Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 113 additions & 75 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,75 +1,113 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

env:
CARGO_TERM_COLOR: always
RUSTFLAGS: --deny warnings
RUSTDOCFLAGS: --deny warnings

jobs:
# Check formatting.
format:
name: Format
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@nightly
with:
components: rustfmt

- name: Check formatting
working-directory: bevy_ios_safearea
run: cargo fmt --all -- --check

# Run Clippy lints.
clippy:
name: Clippy
runs-on: macos-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy

- name: Populate target directory from cache
uses: Leafwing-Studios/cargo-cache@v2
with:
manifest-path: bevy_ios_safearea/Cargo.toml

- name: Run Clippy lints
working-directory: bevy_ios_safearea
run: cargo clippy --workspace --all-features --all-targets -- --deny warnings

# Check documentation.
doc:
name: Docs
runs-on: macos-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@nightly

- name: Populate target directory from cache
uses: Leafwing-Studios/cargo-cache@v2
with:
manifest-path: bevy_ios_safearea/Cargo.toml

- name: Check documentation
working-directory: bevy_ios_safearea
run: cargo doc --workspace --all-features --document-private-items --no-deps
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

env:
CARGO_TERM_COLOR: always
RUSTFLAGS: --deny warnings
RUSTDOCFLAGS: --deny warnings

jobs:
# Check formatting.
format:
name: Format
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@nightly
with:
components: rustfmt

- name: Check formatting
working-directory: bevy_ios_safearea
run: cargo fmt --all -- --check

# Run Clippy lints.
clippy:
name: Clippy
runs-on: macos-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy

- name: Populate target directory from cache
uses: Leafwing-Studios/cargo-cache@v2
with:
manifest-path: bevy_ios_safearea/Cargo.toml

- name: Run Clippy lints
working-directory: bevy_ios_safearea
run: cargo clippy --workspace --all-features --all-targets -- --deny warnings

android_build:
name: Android Build
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Install Dependencies
run: sudo apt-get update; sudo apt-get install pkg-config libx11-dev libasound2-dev libudev-dev lld llvm

- name: Checkout repository
uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v5
with:
java-version: "17"
distribution: "temurin"

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Add Android targets
run: rustup target add aarch64-linux-android
- uses: taiki-e/install-action@v2
with:
tool: cargo-ndk

- name: Populate target directory from cache
uses: Leafwing-Studios/cargo-cache@v2
with:
manifest-path: bevy_ios_safearea/Cargo.toml

- name: Build for Android- game activity
working-directory: bevy_ios_safearea
run: cargo ndk build --workspace --features android-game-activity --target aarch64-linux-android

- name: Build for Android- native activity
working-directory: bevy_ios_safearea
run: cargo ndk build --workspace --features android-native-activity --target aarch64-linux-android

# Check documentation.
doc:
name: Docs
runs-on: macos-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@nightly

- name: Populate target directory from cache
uses: Leafwing-Studios/cargo-cache@v2
with:
manifest-path: bevy_ios_safearea/Cargo.toml

- name: Check documentation
working-directory: bevy_ios_safearea
run: cargo doc --workspace --all-features --document-private-items --no-deps
26 changes: 21 additions & 5 deletions bevy_ios_safearea/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,32 @@ targets = [
"x86_64-apple-darwin",
# iOS
"aarch64-apple-ios",
# android
"aarch64-linux-android",
"armv7-linux-androideabi"
]

[features]
default = []
android-native-activity = ["bevy_winit/android-native-activity"]
android-game-activity = ["bevy_winit/android-game-activity"]

[dependencies]
bevy = { version = "0.16", default-features = false, features = [
"bevy_window",
"bevy_winit",
"bevy_log",
] }
bevy_ecs = {version = "0.16"}
bevy_app = {version = "0.16"}
bevy_reflect = {version = "0.16"}

[target.'cfg(target_os = "ios")'.dependencies]
bevy_window = {version = "0.16"}
bevy_winit = {version = "0.16"}
bevy_log = {version = "0.16"}
winit = { version = "0.30", default-features = false, features = ["rwh_06"] }

[target.'cfg(target_os = "android")'.dependencies]
bevy_window = {version = "0.16"}
bevy_log = {version = "0.16"}
bevy_winit = {version = "0.16"}
jni = "0.21"

[lints.rust]
missing_docs = "warn"
71 changes: 71 additions & 0 deletions bevy_ios_safearea/src/android.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use crate::IosSafeAreaResource;

/// Get the safe area insets for Android.
pub(crate) fn try_get_safe_area() -> Option<IosSafeAreaResource> {
use jni::{
objects::JObject,
sys::{_jobject, JNIInvokeInterface_},
};

let android_app = bevy_window::ANDROID_APP.get()?;
let vm = unsafe {
jni::JavaVM::from_raw(android_app.vm_as_ptr() as *mut *const JNIInvokeInterface_).ok()?
};
let activity = unsafe { JObject::from_raw(android_app.activity_as_ptr() as *mut _jobject) };
let mut env = vm.attach_current_thread().ok()?;

// Get the Window from the Activity
let window = env
.call_method(&activity, "getWindow", "()Landroid/view/Window;", &[])
.ok()?;

let window_obj = window.l().ok()?;

// Get the DecorView from the Window
let decor_view = env
.call_method(&window_obj, "getDecorView", "()Landroid/view/View;", &[])
.ok()?;

let decor_view_obj = decor_view.l().ok()?;

// Get the root window insets
let root_insets = env
.call_method(
&decor_view_obj,
"getRootWindowInsets",
"()Landroid/view/WindowInsets;",
&[],
)
.ok()?;

let insets_obj = root_insets.l().ok()?;

// Get system window insets (for API level 20+)
let top = env
.call_method(&insets_obj, "getSystemWindowInsetTop", "()I", &[])
.ok()?
.i()
.ok()?;
let bottom = env
.call_method(&insets_obj, "getSystemWindowInsetBottom", "()I", &[])
.ok()?
.i()
.ok()?;
let left = env
.call_method(&insets_obj, "getSystemWindowInsetLeft", "()I", &[])
.ok()?
.i()
.ok()?;
let right = env
.call_method(&insets_obj, "getSystemWindowInsetRight", "()I", &[])
.ok()?
.i()
.ok()?;

Some(IosSafeAreaResource {
top: top as f32,
bottom: bottom as f32,
left: left as f32,
right: right as f32,
})
}
7 changes: 6 additions & 1 deletion bevy_ios_safearea/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
#![doc = include_str!("../README.md")]

#[cfg(all(
target_os = "android",
any(feature = "android-native-activity", feature = "android-game-activity")
))]
mod android;
#[cfg(target_os = "ios")]
mod native;
mod plugin;

pub use plugin::{IosSafeArea, IosSafeAreaPlugin, IosSafeAreaResource};
pub use plugin::{IosSafeArea, IosSafeAreaPlugin, IosSafeAreaResource, SafeAreaExt};
Loading