From a93c680789136d3471d8cd7c6d2532c1cad17a20 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Tue, 21 May 2024 09:30:56 +0200 Subject: [PATCH] asset: Store a `PhantomData` lifetime inside `AssetManager` to represent missing ownership semantics --- ndk/src/asset.rs | 17 +++++++++++------ ndk/src/configuration.rs | 2 +- ndk/src/native_activity.rs | 4 +++- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ndk/src/asset.rs b/ndk/src/asset.rs index 35166f49..8d6c6c44 100644 --- a/ndk/src/asset.rs +++ b/ndk/src/asset.rs @@ -7,6 +7,7 @@ use std::{ ffi::{CStr, CString}, io, + marker::PhantomData, os::fd::{FromRawFd, OwnedFd}, ptr::NonNull, }; @@ -14,18 +15,19 @@ use std::{ /// A native [`AAssetManager *`] /// /// [`AAssetManager *`]: https://developer.android.com/ndk/reference/group/asset#aassetmanager -#[derive(Debug)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[doc(alias = "AAssetManager")] -pub struct AssetManager { +pub struct AssetManager<'a> { ptr: NonNull, + _marker: PhantomData<&'a ()>, } // AAssetManager is thread safe. // See https://developer.android.com/ndk/reference/group/asset#aassetmanager -unsafe impl Send for AssetManager {} -unsafe impl Sync for AssetManager {} +unsafe impl<'a> Send for AssetManager<'a> {} +unsafe impl<'a> Sync for AssetManager<'a> {} -impl AssetManager { +impl<'a> AssetManager<'a> { /// Wraps a pointer to [`ffi::AssetManager`] /// /// # Safety @@ -33,7 +35,10 @@ impl AssetManager { /// responsible for guaranteeing the lifetime of this pointer, and should drop the structure /// _before_ the pointer becomes invalid. pub unsafe fn from_ptr(ptr: NonNull) -> Self { - Self { ptr } + Self { + ptr, + _marker: PhantomData, + } } /// Returns the pointer to the native [`ffi::AAssetManager`]. diff --git a/ndk/src/configuration.rs b/ndk/src/configuration.rs index fcd98dda..8673a916 100644 --- a/ndk/src/configuration.rs +++ b/ndk/src/configuration.rs @@ -100,7 +100,7 @@ impl Configuration { self.ptr } - pub fn from_asset_manager(am: &AssetManager) -> Self { + pub fn from_asset_manager(am: &AssetManager<'_>) -> Self { let config = Self::new(); unsafe { ffi::AConfiguration_fromAssetManager(config.ptr().as_mut(), am.ptr().as_mut()); diff --git a/ndk/src/native_activity.rs b/ndk/src/native_activity.rs index 19c8965e..ab2b79a9 100644 --- a/ndk/src/native_activity.rs +++ b/ndk/src/native_activity.rs @@ -107,7 +107,9 @@ impl NativeActivity { } /// This app's asset manager, which can be used to access assets from the `.apk` file. - pub fn asset_manager(&self) -> crate::asset::AssetManager { + pub fn asset_manager(&self) -> crate::asset::AssetManager<'_> { + // SAFETY: Android initializes this field to a valid pointer, and the lifetime of the + // returned AssetManager is constrained to the lifetime of Self. unsafe { crate::asset::AssetManager::from_ptr( NonNull::new(self.ptr.as_ref().assetManager).unwrap(),