Skip to content

Commit

Permalink
Upgrade to ndk 0.9 and delete unused ndk-sys/context dependencies
Browse files Browse the repository at this point in the history
The `ndk` crate received some marginal API upgrades, besides fixing
soundness issues.  Specifcally, `ForeignLooper::add_fd_with_callback()`
now signifies that the incoming file descriptor is a `BorrowedFd` and
the callback is executed on a different thread (where the looper is
polled on the `ThreadLooper`) and must hence be `Send.`.

It appears the `ndk-sys` and `ndk-context` crates are not used directly,
hence they are removed from `Cargo.toml` here.
  • Loading branch information
MarijnS95 committed Jul 18, 2024
1 parent 03cdf93 commit 19fa538
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 11 deletions.
7 changes: 7 additions & 0 deletions .changes/ndk-0.9.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"wry": major
---

**Breaking change**: Upgrade `ndk` crate to `0.9` and delete unused `ndk-sys` and `ndk-context` dependencies. Types from the `ndk` crates are used in public API surface.

**Breaking change**: The public `android_setup()` function now takes `&ThreadLooper` instead of `&ForeignLooper`, signifying that the setup function must be called on the thread where the looper is attached (and the `JNIEnv` argument is already thread-local as well).
4 changes: 1 addition & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,7 @@ kuchiki = { package = "kuchikiki", version = "0.8" }
sha2 = "0.10"
base64 = "0.22"
jni = "0.21"
ndk = "0.7"
ndk-sys = "0.4"
ndk-context = "0.1"
ndk = "0.9"
tao-macros = "0.1"
libc = "0.2"

Expand Down
2 changes: 1 addition & 1 deletion src/android/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ macro_rules! android_binding {
($domain:ident, $package:ident) => {
::wry::android_binding!($domain, $package, ::wry)
};
// use import `android_setup` just to force the import path to use `wry::{}`
// use imported `android_setup` just to force the import path to use `wry::{}`
// as the macro breaks without braces
($domain:ident, $package:ident, $wry:path) => {{
use $wry::{android_setup as _, prelude::*};
Expand Down
12 changes: 9 additions & 3 deletions src/android/main_pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ use std::{os::unix::prelude::*, sync::atomic::Ordering};
use super::{find_class, EvalCallback, EVAL_CALLBACKS, EVAL_ID_GENERATOR, PACKAGE};

static CHANNEL: Lazy<(Sender<WebViewMessage>, Receiver<WebViewMessage>)> = Lazy::new(|| bounded(8));
pub static MAIN_PIPE: Lazy<[RawFd; 2]> = Lazy::new(|| {
pub static MAIN_PIPE: Lazy<[OwnedFd; 2]> = Lazy::new(|| {
let mut pipe: [RawFd; 2] = Default::default();
unsafe { libc::pipe(pipe.as_mut_ptr()) };
pipe
unsafe { pipe.map(|fd| OwnedFd::from_raw_fd(fd)) }
});

pub struct MainPipe<'a> {
Expand All @@ -32,7 +32,13 @@ impl<'a> MainPipe<'a> {
pub(crate) fn send(message: WebViewMessage) {
let size = std::mem::size_of::<bool>();
if let Ok(()) = CHANNEL.0.send(message) {
unsafe { libc::write(MAIN_PIPE[1], &true as *const _ as *const _, size) };
unsafe {
libc::write(
MAIN_PIPE[1].as_raw_fd(),
&true as *const _ as *const _,
size,
)
};
}
}

Expand Down
12 changes: 8 additions & 4 deletions src/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ use jni::{
JNIEnv,
};
use kuchiki::NodeRef;
use ndk::looper::{FdEvent, ForeignLooper};
use ndk::looper::{FdEvent, ThreadLooper};
use once_cell::sync::OnceCell;
use raw_window_handle::HasWindowHandle;
use sha2::{Digest, Sha256};
use std::{
borrow::Cow,
collections::HashMap,
os::fd::{AsFd as _, AsRawFd as _},
sync::{atomic::AtomicI32, mpsc::channel, Mutex},
};

Expand Down Expand Up @@ -75,10 +76,13 @@ pub static EVAL_CALLBACKS: once_cell::sync::OnceCell<Mutex<HashMap<i32, EvalCall
once_cell::sync::OnceCell::new();

/// Sets up the necessary logic for wry to be able to create the webviews later.
///
/// This function must be run on the thread where the [`JNIEnv`] is registered and the looper is local,
/// hence the requirement for a [`ThreadLooper`].
pub unsafe fn android_setup(
package: &str,
mut env: JNIEnv,
looper: &ForeignLooper,
looper: &ThreadLooper,
activity: GlobalRef,
) {
PACKAGE.get_or_init(move || package.to_string());
Expand Down Expand Up @@ -108,10 +112,10 @@ pub unsafe fn android_setup(
};

looper
.add_fd_with_callback(MAIN_PIPE[0], FdEvent::INPUT, move |_| {
.add_fd_with_callback(MAIN_PIPE[0].as_fd(), FdEvent::INPUT, move |fd, _event| {
let size = std::mem::size_of::<bool>();
let mut wake = false;
if libc::read(MAIN_PIPE[0], &mut wake as *mut _ as *mut _, size) == size as libc::ssize_t {
if libc::read(fd.as_raw_fd(), &mut wake as *mut _ as *mut _, size) == size as libc::ssize_t {
main_pipe.recv().is_ok()
} else {
false
Expand Down

0 comments on commit 19fa538

Please sign in to comment.