basic saf impl

This commit is contained in:
gabriel 2024-02-03 01:25:10 -04:00
parent 3c25be4c63
commit d6187f7af7
6 changed files with 80 additions and 2 deletions

View file

@ -0,0 +1,6 @@
#pragma once
class AndroidUtils {
public:
static int openDocument(const char* directory, const char* mode);
};

View file

@ -21,6 +21,10 @@
#include <unistd.h> // For ftruncate
#endif
#ifdef __ANDROID__
#include "android_utils.hpp"
#endif
IOFile::IOFile(const std::filesystem::path& path, const char* permissions) : handle(nullptr) { open(path, permissions); }
bool IOFile::open(const std::filesystem::path& path, const char* permissions) {
@ -34,8 +38,17 @@ bool IOFile::open(const char* filename, const char* permissions) {
if (isOpen()) {
close();
}
#ifdef __ANDROID__
std::string path(filename);
if(path.find("://") != std::string::npos){ //IF SAF URI
handle = fdopen(AndroidUtils::openDocument(filename, permissions), permissions);
} else {
handle = std::fopen(filename, permissions);
}
#else
handle = std::fopen(filename, permissions);
#endif
return isOpen();
}

View file

@ -7,6 +7,7 @@
#include "emulator.hpp"
#include "renderer_gl/renderer_gl.hpp"
#include "services/hid.hpp"
#include "android_utils.hpp"
std::unique_ptr<Emulator> emulator = nullptr;
HIDService* hidService = nullptr;
@ -33,6 +34,23 @@ JNIEnv* jniEnv() {
return env;
}
int AndroidUtils::openDocument(const char* path, const char* perms) {
auto env = jniEnv();
auto clazz = env->FindClass("com/panda3ds/pandroid/AlberDriver");
auto method = env->GetStaticMethodID(clazz, "openDocument", "(Ljava/lang/String;Ljava/lang/String;)I");
jstring uri = env->NewStringUTF(path);
jstring jmode = env->NewStringUTF(perms);
jint result = env->CallStaticIntMethod(clazz, method, uri, jmode);
env->DeleteLocalRef(uri);
env->DeleteLocalRef(jmode);
return (int)result;
}
extern "C" {
#define MAKE_SETTING(functionName, type, settingName) \

View file

@ -1,7 +1,21 @@
package com.panda3ds.pandroid;
import android.content.Context;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.system.Os;
import android.system.OsConstants;
import android.util.Log;
import com.panda3ds.pandroid.app.PandroidApplication;
import com.panda3ds.pandroid.utils.Constants;
import com.panda3ds.pandroid.utils.FileUtils;
import com.panda3ds.pandroid.utils.GameUtils;
import java.io.File;
import java.util.Objects;
public class AlberDriver {
AlberDriver() { super(); }
@ -24,5 +38,25 @@ public class AlberDriver {
public static native void setShaderJitEnabled(boolean enable);
public static int openDocument(String path, String mode){
try {
mode = mode.substring(0,1);
Context context = PandroidApplication.getAppContext();
Uri uri = FileUtils.obtainUri(path);
ParcelFileDescriptor parcel;
if (Objects.equals(uri.getScheme(), "game")) {
uri = FileUtils.obtainUri(GameUtils.getCurrentGame().getRomPath());
parcel = context.getContentResolver().openFileDescriptor(uri, "r");
} else {
parcel = context.getContentResolver().openFileDescriptor(uri, mode);
}
int fd = parcel.detachFd();
parcel.close();
return fd;
} catch (Exception e){
throw new RuntimeException(e);
}
}
static { System.loadLibrary("Alber"); }
}

View file

@ -5,6 +5,7 @@ import android.content.Intent;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.system.Os;
import android.system.OsConstants;
import android.util.Log;
import androidx.documentfile.provider.DocumentFile;
@ -243,4 +244,8 @@ public class FileUtils {
return result;
}
public static Uri obtainUri(String path) {
return parseFile(path).getUri();
}
}

View file

@ -40,7 +40,9 @@ public class GameUtils {
public static void launch(Context context, GameMetadata game) {
currentGame = game;
String path = FileUtils.obtainRealPath(game.getRomPath());
String[] parts = Uri.decode(game.getRomPath()).split("/");
String name = parts[parts.length-1];
String path = "game://internal/"+name;
context.startActivity(new Intent(context, GameActivity.class).putExtra(Constants.ACTIVITY_PARAMETER_PATH, path));
}