Skip to content

Commit

Permalink
Android: rework backend to use android_activity crate
Browse files Browse the repository at this point in the history
This updates the Android backend to use the android_activity crate instead
of ndk-glue. This solves a few issues:
1. The backend is agnostic of the application's choice of Activity base
   class
2. Winit is no longer responsible for handling any Java synchronization
   details, since these are encapsulated by the design of
   android_activity
3. The backend no longer depends on global / static getters for state
   such as the native_window() which puts it in a better position to
   support running multiple activities within a single Android process.
4. Redraw requests are flagged, not queued, in a way that avoids taking
   priority over user events (resolves rust-windowing#2299)

Addresses: PR rust-windowing#1892
Addresses: PR rust-windowing#2307
Addresses: PR rust-windowing#2343

Addresses: rust-windowing#2293
Resolves: rust-windowing#2299
  • Loading branch information
rib committed Aug 31, 2022
1 parent 2e4338b commit 7f2ad93
Show file tree
Hide file tree
Showing 4 changed files with 643 additions and 401 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ simple_logger = "2.1.0"
[target.'cfg(target_os = "android")'.dependencies]
# Coordinate the next winit release with android-ndk-rs: https://github.com/rust-windowing/winit/issues/1995
ndk = "0.7.0"
ndk-glue = "0.7.0"
android-activity = "0.2"

[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies]
objc = "0.2.7"
Expand Down
10 changes: 10 additions & 0 deletions src/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,18 @@ impl<T> EventLoopBuilder<T> {
/// `WINIT_UNIX_BACKEND`. Legal values are `x11` and `wayland`.
/// If it is not set, winit will try to connect to a Wayland connection, and if that fails,
/// will fall back on X11. If this variable is set with any other value, winit will panic.
/// - **Android:** Must be configured with an `AndroidApp` from `android_main()` by calling
/// [`.with_android_app(app)`] before calling `.build()`.
///
/// [`platform`]: crate::platform
#[cfg_attr(
target_os = "android",
doc = "[`.with_android_app(app)`]: crate::platform::android::EventLoopBuilderExtAndroid::with_android_app"
)]
#[cfg_attr(
not(target_os = "android"),
doc = "[`.with_android_app(app)`]: #only-available-on-android"
)]
#[inline]
pub fn build(&mut self) -> EventLoop<T> {
static EVENT_LOOP_CREATED: OnceCell<()> = OnceCell::new();
Expand Down
24 changes: 19 additions & 5 deletions src/platform/android.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#![cfg(any(target_os = "android"))]

use crate::{
event_loop::{EventLoop, EventLoopWindowTarget},
event_loop::{EventLoop, EventLoopBuilder, EventLoopWindowTarget},
window::{Window, WindowBuilder},
};
use ndk::configuration::Configuration;
use ndk_glue::Rect;

use android_activity::{AndroidApp, ConfigurationRef, Rect};

/// Additional methods on [`EventLoop`] that are specific to Android.
pub trait EventLoopExtAndroid {}
Expand All @@ -19,15 +19,15 @@ pub trait EventLoopWindowTargetExtAndroid {}
pub trait WindowExtAndroid {
fn content_rect(&self) -> Rect;

fn config(&self) -> Configuration;
fn config(&self) -> ConfigurationRef;
}

impl WindowExtAndroid for Window {
fn content_rect(&self) -> Rect {
self.window.content_rect()
}

fn config(&self) -> Configuration {
fn config(&self) -> ConfigurationRef {
self.window.config()
}
}
Expand All @@ -38,3 +38,17 @@ impl<T> EventLoopWindowTargetExtAndroid for EventLoopWindowTarget<T> {}
pub trait WindowBuilderExtAndroid {}

impl WindowBuilderExtAndroid for WindowBuilder {}

pub trait EventLoopBuilderExtAndroid {
/// Associates the `AndroidApp` that was passed to `android_main()` with the event loop
///
/// This must be called on Android since the `AndroidApp` is not global state.
fn with_android_app(&mut self, app: AndroidApp) -> &mut Self;
}

impl<T> EventLoopBuilderExtAndroid for EventLoopBuilder<T> {
fn with_android_app(&mut self, app: AndroidApp) -> &mut Self {
self.platform_specific.android_app = Some(app);
self
}
}
Loading

0 comments on commit 7f2ad93

Please sign in to comment.