check file exists on android (#934)
* check file exists on android * more * more * more
This commit is contained in:
parent
66a74b5693
commit
82c22dc18e
@ -5,6 +5,8 @@
|
||||
<uses-feature android:name="android.hardware.vulkan.version" android:required="true"
|
||||
android:version="0x00401000" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="Gopher64">
|
||||
|
||||
@ -80,6 +80,9 @@ pub fn save(
|
||||
elapsed_time: i64,
|
||||
ram_path: &std::string::String,
|
||||
) {
|
||||
if cfg!(target_os = "android") {
|
||||
return;
|
||||
}
|
||||
update_rtc_regs(gb_cart, elapsed_time);
|
||||
|
||||
if let Ok(file) = std::fs::File::create(ram_path) {
|
||||
|
||||
@ -68,13 +68,22 @@ bind_java_type! {
|
||||
},
|
||||
}
|
||||
|
||||
bind_java_type! {
|
||||
ParcelFileDescriptor => "android.os.ParcelFileDescriptor",
|
||||
methods {
|
||||
fn close() -> (),
|
||||
},
|
||||
}
|
||||
|
||||
bind_java_type! {
|
||||
AndroidContentResolver => "android.content.ContentResolver",
|
||||
type_map = {
|
||||
AndroidUri => "android.net.Uri",
|
||||
ParcelFileDescriptor => "android.os.ParcelFileDescriptor",
|
||||
},
|
||||
methods {
|
||||
fn take_persistable_uri_permission(uri: AndroidUri, flags: jint) -> (),
|
||||
fn open_file_descriptor(uri: AndroidUri, mode: JString) -> ParcelFileDescriptor,
|
||||
},
|
||||
}
|
||||
|
||||
@ -160,11 +169,9 @@ fn list_controllers_on_jvm(env: &mut Env<'_>) -> jni::errors::Result<Vec<Control
|
||||
continue;
|
||||
}
|
||||
|
||||
if !device.supports_source(env, source_gamepad)? {
|
||||
continue;
|
||||
}
|
||||
|
||||
if !device.supports_source(env, source_joystick)? {
|
||||
let supports_gamepad = device.supports_source(env, source_gamepad)?;
|
||||
let supports_joystick = device.supports_source(env, source_joystick)?;
|
||||
if !supports_gamepad && !supports_joystick {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -221,7 +228,7 @@ fn open_uri_on_jvm(env: &mut Env<'_>, path: &str) -> jni::errors::Result<()> {
|
||||
let raw_activity_global = app.activity_as_ptr() as jni::sys::jobject;
|
||||
let activity = unsafe { env.as_cast_raw::<Global<AndroidActivity>>(&raw_activity_global)? };
|
||||
|
||||
let uri_string = JString::from_str(env, path.to_string())?;
|
||||
let uri_string = JString::from_str(env, path)?;
|
||||
let uri = AndroidUri::parse(env, &uri_string)?;
|
||||
|
||||
let action_view = AndroidIntent::ACTION_VIEW(env)?;
|
||||
@ -305,6 +312,50 @@ pub fn get_dirs() -> ui::Dirs {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rom_exists(path: &str) -> bool {
|
||||
let path = path.to_string();
|
||||
|
||||
let vm = if let Ok(app) = ANDROID_APP.lock()
|
||||
&& let Some(app) = app.as_ref()
|
||||
{
|
||||
unsafe { JavaVM::from_raw(app.vm_as_ptr().cast()) }
|
||||
} else {
|
||||
eprintln!("Android app not initialized");
|
||||
return false;
|
||||
};
|
||||
if let Err(err) = vm.attach_current_thread(|env| rom_exists_on_jvm(env, path)) {
|
||||
eprintln!("JNI error while opening URI: {err:?}");
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn rom_exists_on_jvm(env: &mut Env<'_>, path: String) -> jni::errors::Result<()> {
|
||||
if let Ok(app) = ANDROID_APP.lock()
|
||||
&& let Some(app) = app.as_ref()
|
||||
{
|
||||
let raw_activity_global = app.activity_as_ptr() as jni::sys::jobject;
|
||||
let activity = unsafe { env.as_cast_raw::<Global<AndroidActivity>>(&raw_activity_global)? };
|
||||
let path = JString::from_str(env, path)?;
|
||||
let mode = JString::from_str(env, "r")?;
|
||||
let uri = AndroidUri::parse(env, &path)?;
|
||||
|
||||
let content_resolver = activity.as_ref().get_content_resolver(env)?;
|
||||
let parcel_file_descriptor = content_resolver.open_file_descriptor(env, &uri, &mode);
|
||||
if let Ok(descriptor) = parcel_file_descriptor
|
||||
&& !descriptor.is_null()
|
||||
{
|
||||
descriptor.close(env)?;
|
||||
return Ok(());
|
||||
} else {
|
||||
return Err(jni::errors::Error::ObjectFreed);
|
||||
}
|
||||
} else {
|
||||
eprintln!("Android app not initialized");
|
||||
return Err(jni::errors::Error::UninitializedJavaVM);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "system" fn Java_io_github_gopher64_gopher64_SlintActivity_nativeOnActivityResult<
|
||||
'caller,
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
use crate::ui;
|
||||
#[cfg(target_os = "android")]
|
||||
use crate::ui::android;
|
||||
use slint::Model;
|
||||
#[cfg(not(target_os = "android"))]
|
||||
use slint::winit_030::WinitWindowAccessor;
|
||||
@ -93,13 +95,20 @@ fn file_dropped(app: &AppWindow) {
|
||||
});
|
||||
}
|
||||
|
||||
fn rom_exists(path: &str) -> bool {
|
||||
#[cfg(not(target_os = "android"))]
|
||||
return std::fs::exists(path).unwrap_or(false);
|
||||
#[cfg(target_os = "android")]
|
||||
return android::rom_exists(path);
|
||||
}
|
||||
|
||||
fn local_game_window(app: &AppWindow, config: &ui::config::Config) {
|
||||
app.set_recent_roms(slint::ModelRc::from(std::rc::Rc::new(
|
||||
slint::VecModel::from(
|
||||
config
|
||||
.recent_roms
|
||||
.iter()
|
||||
.filter(|x| std::fs::exists(x).unwrap_or(false))
|
||||
.filter(|x| rom_exists(x))
|
||||
.map(|x| {
|
||||
(
|
||||
x.into(),
|
||||
@ -585,7 +594,7 @@ pub fn run_rom(
|
||||
for rom in handle.get_recent_roms().iter() {
|
||||
if rom.0 != file_path.to_str().unwrap()
|
||||
&& recent_roms.row_count() < 5
|
||||
&& std::fs::exists(&rom.0).unwrap_or(false)
|
||||
&& rom_exists(&rom.0)
|
||||
{
|
||||
recent_roms.push(rom);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user