From d4e4a929821d87f4b112f3184b4b50799dd99386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 30 Jun 2022 19:42:45 +0000 Subject: [PATCH] android - fix issues other than the rendering (#5130) # Objective - Make Bevy work on android ## Solution - Update android metadata and add a few more - Set the target sdk to 31 as it will soon (in august) be the minimum sdk level for play store - Remove the custom code to create an activity and use ndk-glue macro instead - Delay window creation event on android - Set the example with compatibility settings for wgpu. Those are needed for Bevy to work on my 2019 android tablet - Add a few details on how to debug in case of failures - Fix running the example on emulator. This was failing because of the name of the example Bevy still doesn't work on android with this, audio features need to be disabled because of an ndk-glue version mismatch: rodio depends on 0.6.2, winit on 0.5.2. You can test with: ``` cargo apk run --release --example android_example --no-default-features --features "bevy_winit,render" ``` --- .github/workflows/validation-jobs.yml | 5 +---- Cargo.toml | 13 +++++++----- crates/bevy_derive/src/bevy_main.rs | 16 ++++----------- crates/bevy_winit/src/lib.rs | 4 ++++ examples/README.md | 29 ++++++++++++++++++++------- examples/README.md.tpl | 29 ++++++++++++++++++++------- examples/android/android.rs | 11 +++++++++- 7 files changed, 71 insertions(+), 36 deletions(-) diff --git a/.github/workflows/validation-jobs.yml b/.github/workflows/validation-jobs.yml index ec060da4af..1c5e8d553e 100644 --- a/.github/workflows/validation-jobs.yml +++ b/.github/workflows/validation-jobs.yml @@ -52,9 +52,6 @@ jobs: target/ key: ${{ runner.os }}-cargo-build-android-${{ hashFiles('**/Cargo.toml') }} - - name: Uninstall android-31 - run: $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --uninstall "platforms;android-31" - - name: Install Android targets run: rustup target add aarch64-linux-android armv7-linux-androideabi @@ -62,7 +59,7 @@ jobs: run: cargo install --force cargo-apk - name: Build APK - run: cargo apk build --example android + run: cargo apk build --example android_example run-examples-on-windows: runs-on: windows-latest diff --git a/Cargo.toml b/Cargo.toml index 69ec5086a5..3a094ff9f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1467,19 +1467,22 @@ hidden = true # Android [[example]] crate-type = ["cdylib"] -name = "android" +name = "android_example" path = "examples/android/android.rs" -[package.metadata.example.android] +[package.metadata.example.android_example] hidden = true [package.metadata.android] -apk_label = "Bevy Example" +package = "org.bevyengine.example" +apk_name = "bevyexample" assets = "assets" resources = "assets/android-res" build_targets = ["aarch64-linux-android", "armv7-linux-androideabi"] -min_sdk_version = 16 -target_sdk_version = 29 + +[package.metadata.android.sdk] +target_sdk_version = 31 [package.metadata.android.application] icon = "@mipmap/ic_launcher" +label = "Bevy Example" diff --git a/crates/bevy_derive/src/bevy_main.rs b/crates/bevy_derive/src/bevy_main.rs index 4a2650f36c..6ec1363097 100644 --- a/crates/bevy_derive/src/bevy_main.rs +++ b/crates/bevy_derive/src/bevy_main.rs @@ -10,19 +10,11 @@ pub fn bevy_main(_attr: TokenStream, item: TokenStream) -> TokenStream { ); TokenStream::from(quote! { - #[no_mangle] + // use ndk-glue macro to create an activity: https://github.com/rust-windowing/android-ndk-rs/tree/master/ndk-macro #[cfg(target_os = "android")] - unsafe extern "C" fn ANativeActivity_onCreate( - activity: *mut std::os::raw::c_void, - saved_state: *mut std::os::raw::c_void, - saved_state_size: usize, - ) { - bevy::ndk_glue::init( - activity as _, - saved_state as _, - saved_state_size as _, - main, - ); + #[cfg_attr(target_os = "android", bevy::ndk_glue::main(backtrace = "on", ndk_glue = "bevy::ndk_glue"))] + fn android_main() { + main() } #[no_mangle] diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 88e3f81126..4ab437d8c1 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -48,9 +48,13 @@ impl Plugin for WinitPlugin { #[cfg(target_arch = "wasm32")] app.add_plugin(web_resize::CanvasParentResizePlugin); let event_loop = EventLoop::new(); + #[cfg(not(target_os = "android"))] let mut create_window_reader = WinitCreateWindowReader::default(); + #[cfg(target_os = "android")] + let create_window_reader = WinitCreateWindowReader::default(); // Note that we create a window here "early" because WASM/WebGL requires the window to exist prior to initializing // the renderer. + #[cfg(not(target_os = "android"))] handle_create_window_events(&mut app.world, &event_loop, &mut create_window_reader.0); app.insert_resource(create_window_reader) .insert_non_send_resource(event_loop); diff --git a/examples/README.md b/examples/README.md index f28805e2e9..5b4ac1fc95 100644 --- a/examples/README.md +++ b/examples/README.md @@ -346,32 +346,47 @@ When using `NDK (Side by side)`, the environment variable `ANDROID_NDK_ROOT` mus To run on a device setup for Android development, run: ```sh -cargo apk run --example android +cargo apk run --example android_example ``` -:warning: At this time Bevy does not work in Android Emulator. - When using Bevy as a library, the following fields must be added to `Cargo.toml`: ```toml [package.metadata.android] build_targets = ["aarch64-linux-android", "armv7-linux-androideabi"] -target_sdk_version = 29 -min_sdk_version = 16 + +[package.metadata.android.sdk] +target_sdk_version = 31 ``` Please reference `cargo-apk` [README](https://crates.io/crates/cargo-apk) for other Android Manifest fields. +### Debugging + +You can view the logs with the following command: + +```sh +adb logcat | grep 'RustStdoutStderr\|bevy\|wgpu' +``` + +In case of an error getting a GPU or setting it up, you can try settings logs of `wgpu_hal` to `DEBUG` to get more informations. + +Sometimes, running the app complains about an unknown activity. This may be fixed by uninstalling the application: + +```sh +adb uninstall org.bevyengine.example +``` + ### Old phones -Bevy by default targets Android API level 29 in its examples which is the +Bevy by default targets Android API level 31 in its examples which is the [Play Store's minimum API to upload or update apps](https://developer.android.com/distribute/best-practices/develop/target-sdk). Users of older phones may want to use an older API when testing. To use a different API, the following fields must be updated in Cargo.toml: ```toml -[package.metadata.android] +[package.metadata.android.sdk] target_sdk_version = >>API<< min_sdk_version = >>API or less<< ``` diff --git a/examples/README.md.tpl b/examples/README.md.tpl index bdc54eb868..dff0e1506c 100644 --- a/examples/README.md.tpl +++ b/examples/README.md.tpl @@ -98,32 +98,47 @@ When using `NDK (Side by side)`, the environment variable `ANDROID_NDK_ROOT` mus To run on a device setup for Android development, run: ```sh -cargo apk run --example android +cargo apk run --example android_example ``` -:warning: At this time Bevy does not work in Android Emulator. - When using Bevy as a library, the following fields must be added to `Cargo.toml`: ```toml [package.metadata.android] build_targets = ["aarch64-linux-android", "armv7-linux-androideabi"] -target_sdk_version = 29 -min_sdk_version = 16 + +[package.metadata.android.sdk] +target_sdk_version = 31 ``` Please reference `cargo-apk` [README](https://crates.io/crates/cargo-apk) for other Android Manifest fields. +### Debugging + +You can view the logs with the following command: + +```sh +adb logcat | grep 'RustStdoutStderr\|bevy\|wgpu' +``` + +In case of an error getting a GPU or setting it up, you can try settings logs of `wgpu_hal` to `DEBUG` to get more informations. + +Sometimes, running the app complains about an unknown activity. This may be fixed by uninstalling the application: + +```sh +adb uninstall org.bevyengine.example +``` + ### Old phones -Bevy by default targets Android API level 29 in its examples which is the +Bevy by default targets Android API level 31 in its examples which is the [Play Store's minimum API to upload or update apps](https://developer.android.com/distribute/best-practices/develop/target-sdk). Users of older phones may want to use an older API when testing. To use a different API, the following fields must be updated in Cargo.toml: ```toml -[package.metadata.android] +[package.metadata.android.sdk] target_sdk_version = >>API<< min_sdk_version = >>API or less<< ``` diff --git a/examples/android/android.rs b/examples/android/android.rs index 8914232398..3fcae59b16 100644 --- a/examples/android/android.rs +++ b/examples/android/android.rs @@ -1,9 +1,18 @@ -use bevy::prelude::*; +use bevy::{ + prelude::*, + render::settings::{WgpuSettings, WgpuSettingsPriority}, +}; // the `bevy_main` proc_macro generates the required android boilerplate #[bevy_main] fn main() { App::new() + // This configures the app to use the most compatible rendering settings. + // They help with compatibilty with as many devices as possible. + .insert_resource(WgpuSettings { + priority: WgpuSettingsPriority::Compatibility, + ..default() + }) .add_plugins(DefaultPlugins) .add_startup_system(setup) .run();