Skip to content

Commit

Permalink
Android: make scoped storage more reliable
Browse files Browse the repository at this point in the history
  • Loading branch information
Hydr8gon committed Dec 15, 2023
1 parent 6b1d3a8 commit ce90e52
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 112 deletions.
2 changes: 1 addition & 1 deletion Makefile.switch
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
CFLAGS := -g -Wall -Ofast -flto -ffunction-sections \
$(ARCH) $(DEFINES)

CFLAGS += $(INCLUDE) -D__SWITCH__ #-DDEBUG
CFLAGS += $(INCLUDE) -D__SWITCH__ -DNO_FDOPEN #-DDEBUG

CXXFLAGS := $(CFLAGS) -fno-rtti -std=c++11

Expand Down
2 changes: 1 addition & 1 deletion Makefile.vita
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
NAME := noods
BUILD := build-vita
SOURCES := src src/common src/vita
ARGS := -Ofast -flto -std=c++11 -march=armv7-a -mtune=generic-armv7-a #-DDEBUG
ARGS := -Ofast -flto -std=c++11 -march=armv7-a -mtune=generic-armv7-a -DNO_FDOPEN #-DDEBUG
LIBS := -Wl,-q -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -lvita2d -lSceAppMgr_stub -lSceAudio_stub -lSceCommonDialog_stub \
-lSceCtrl_stub -lSceDisplay_stub -lSceGxm_stub -lSceRegistryMgr_stub -lSceSysmodule_stub -lScePgf_stub -lSceTouch_stub -lScePower_stub

Expand Down
2 changes: 1 addition & 1 deletion Makefile.wiiu
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ INCLUDES := src src/common src/wiiu
CFLAGS := -g -Wall -Ofast -flto -ffunction-sections -fpermissive \
$(MACHDEP)

CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__
CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__ -DNO_FDOPEN

CXXFLAGS := $(CFLAGS)

Expand Down
45 changes: 23 additions & 22 deletions src/android/cpp/interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ int vibrateStrength = 1;
int keyBinds[12] = {};

std::string ndsPath = "", gbaPath = "";
std::string ndsSave = "", gbaSave = "";
int ndsRomFd = -1, gbaRomFd = -1;
int ndsSaveFd = -1, gbaSaveFd = -1;
Core *core = nullptr;
ScreenLayout layout;
uint32_t framebuffer[256 * 192 * 8];
Expand Down Expand Up @@ -113,15 +114,11 @@ extern "C" JNIEXPORT jboolean JNICALL Java_com_hydra_noods_FileBrowser_loadSetti
return false;
}

extern "C" JNIEXPORT void JNICALL Java_com_hydra_noods_FileBrowser_getNdsIcon(JNIEnv *env, jobject obj, jstring romName, jobject bitmap)
extern "C" JNIEXPORT void JNICALL Java_com_hydra_noods_FileBrowser_getNdsIcon(JNIEnv *env, jobject obj, jint fd, jobject bitmap)
{
// Get the NDS icon
const char *str = env->GetStringUTFChars(romName, nullptr);
NdsIcon icon(str);
env->ReleaseStringUTFChars(romName, str);

// Copy the data to the bitmap
// Read an NDS icon and copy its data to the bitmap
uint32_t *data;
NdsIcon icon("", fd);
AndroidBitmap_lockPixels(env, bitmap, (void**)&data);
memcpy(data, icon.getIcon(), 32 * 32 * sizeof(uint32_t));
AndroidBitmap_unlockPixels(env, bitmap);
Expand All @@ -133,7 +130,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_hydra_noods_FileBrowser_startCore(JNI
try
{
if (core) delete core;
core = new Core(ndsPath, gbaPath, 0, ndsSave, gbaSave);
core = new Core(ndsPath, gbaPath, "", "", 0, ndsRomFd, gbaRomFd, ndsSaveFd, gbaSaveFd);
return 0;
}
catch (CoreError e)
Expand All @@ -142,42 +139,46 @@ extern "C" JNIEXPORT jint JNICALL Java_com_hydra_noods_FileBrowser_startCore(JNI
}
}

extern "C" JNIEXPORT jstring JNICALL Java_com_hydra_noods_FileBrowser_getNdsPath(JNIEnv* env, jobject obj)
extern "C" JNIEXPORT jboolean JNICALL Java_com_hydra_noods_FileBrowser_isNdsLoaded(JNIEnv* env, jobject obj)
{
return env->NewStringUTF(ndsPath.c_str());
// Check if an NDS ROM has been loaded
return ndsPath != "" || ndsRomFd != -1;
}

extern "C" JNIEXPORT jstring JNICALL Java_com_hydra_noods_FileBrowser_getGbaPath(JNIEnv* env, jobject obj)
extern "C" JNIEXPORT jboolean JNICALL Java_com_hydra_noods_FileBrowser_isGbaLoaded(JNIEnv* env, jobject obj)
{
return env->NewStringUTF(gbaPath.c_str());
// Check if a GBA ROM has been loaded
return gbaPath != "" || gbaRomFd != -1;
}

extern "C" JNIEXPORT void JNICALL Java_com_hydra_noods_FileBrowser_setNdsPath(JNIEnv* env, jobject obj, jstring value)
{
// Set the NDS ROM file path
const char *str = env->GetStringUTFChars(value, nullptr);
ndsPath = str;
env->ReleaseStringUTFChars(value, str);
}

extern "C" JNIEXPORT void JNICALL Java_com_hydra_noods_FileBrowser_setGbaPath(JNIEnv* env, jobject obj, jstring value)
{
// Set the GBA ROM file path
const char *str = env->GetStringUTFChars(value, nullptr);
gbaPath = str;
env->ReleaseStringUTFChars(value, str);
}

extern "C" JNIEXPORT void JNICALL Java_com_hydra_noods_FileBrowser_setNdsSave(JNIEnv* env, jobject obj, jstring value)
extern "C" JNIEXPORT void JNICALL Java_com_hydra_noods_FileBrowser_setNdsFds(JNIEnv* env, jobject obj, jint romFd, jint saveFd)
{
const char *str = env->GetStringUTFChars(value, nullptr);
ndsSave = str;
env->ReleaseStringUTFChars(value, str);
// Set the NDS ROM file descriptors
ndsRomFd = romFd;
ndsSaveFd = saveFd;
}

extern "C" JNIEXPORT void JNICALL Java_com_hydra_noods_FileBrowser_setGbaSave(JNIEnv* env, jobject obj, jstring value)
extern "C" JNIEXPORT void JNICALL Java_com_hydra_noods_FileBrowser_setGbaFds(JNIEnv* env, jobject obj, jint romFd, jint saveFd)
{
const char *str = env->GetStringUTFChars(value, nullptr);
gbaSave = str;
env->ReleaseStringUTFChars(value, str);
// Set the GBA ROM file descriptors
gbaRomFd = romFd;
gbaSaveFd = saveFd;
}

extern "C" JNIEXPORT void JNICALL Java_com_hydra_noods_NooActivity_startAudio(JNIEnv* env, jobject obj)
Expand Down Expand Up @@ -456,7 +457,7 @@ extern "C" JNIEXPORT void JNICALL Java_com_hydra_noods_NooActivity_writeSave(JNI
extern "C" JNIEXPORT void JNICALL Java_com_hydra_noods_NooActivity_restartCore(JNIEnv *env, jobject obj)
{
if (core) delete core;
core = new Core(ndsPath, gbaPath, 0, ndsSave, gbaSave);
core = new Core(ndsPath, gbaPath, "", "", 0, ndsRomFd, gbaRomFd, ndsSaveFd, gbaSaveFd);
}

extern "C" JNIEXPORT void JNICALL Java_com_hydra_noods_NooActivity_pressScreen(JNIEnv *env, jobject obj, jint x, jint y)
Expand Down
64 changes: 31 additions & 33 deletions src/android/java/com/hydra/noods/FileBrowser.java
Original file line number Diff line number Diff line change
Expand Up @@ -389,10 +389,12 @@ private void update()
// If a ROM of the other type is already loaded, ask if it should be loaded alongside the new ROM
if (ext.equals(".nds"))
{
setNdsPath(getRomPath(file));
setNdsSave(getRomSave(file));
if (scoped)
setNdsFds(getRomFd(file), getSaveFd(file));
else
setNdsPath(file.getUri().getPath());

if (!getGbaPath().equals(""))
if (isGbaLoaded())
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Loading NDS ROM");
Expand All @@ -413,6 +415,7 @@ public void onClick(DialogInterface dialog, int id)
public void onClick(DialogInterface dialog, int id)
{
setGbaPath("");
setGbaFds(-1, -1);
tryStartCore();
}
});
Expand All @@ -423,6 +426,7 @@ public void onClick(DialogInterface dialog, int id)
public void onCancel(DialogInterface dialog)
{
setGbaPath("");
setGbaFds(-1, -1);
tryStartCore();
}
});
Expand All @@ -433,10 +437,12 @@ public void onCancel(DialogInterface dialog)
}
else
{
setGbaPath(getRomPath(file));
setGbaSave(getRomSave(file));
if (scoped)
setGbaFds(getRomFd(file), getSaveFd(file));
else
setGbaPath(file.getUri().getPath());

if (!getNdsPath().equals(""))
if (isNdsLoaded())
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Loading GBA ROM");
Expand All @@ -457,6 +463,7 @@ public void onClick(DialogInterface dialog, int id)
public void onClick(DialogInterface dialog, int id)
{
setNdsPath("");
setNdsFds(-1, -1);
tryStartCore();
}
});
Expand All @@ -467,6 +474,7 @@ public void onClick(DialogInterface dialog, int id)
public void onCancel(DialogInterface dialog)
{
setNdsPath("");
setNdsFds(-1, -1);
tryStartCore();
}
});
Expand Down Expand Up @@ -510,7 +518,7 @@ public int compare(DocumentFile f1, DocumentFile f2)
{
fileNames.add(files[i].getName());
Bitmap bitmap = Bitmap.createBitmap(32, 32, Bitmap.Config.ARGB_8888);
getNdsIcon(getRomPath(files[i]), bitmap);
getNdsIcon(getRomFd(files[i]), bitmap);
fileIcons.add(bitmap);
fileUris.add(files[i].getUri());
}
Expand All @@ -526,71 +534,61 @@ else if (ext.equals(".gba"))
fileView.setAdapter(new FileAdapter(this, fileNames, fileIcons));
}

private String getRomPath(DocumentFile file)
private int getRomFd(DocumentFile rom)
{
// Get the raw file path in non-scoped mode
if (!scoped)
return file.getUri().getPath();

try
{
// Get a descriptor for the file in scoped mode
ParcelFileDescriptor desc = getContentResolver().openFileDescriptor(file.getUri(), "r");
return "/proc/self/fd/" + desc.detachFd();
return getContentResolver().openFileDescriptor(rom.getUri(), "r").detachFd();
}
catch (Exception e)
{
// Oh well, I guess
return "";
return -1;
}
}

private String getRomSave(DocumentFile file)
private int getSaveFd(DocumentFile rom)
{
// Let the core handle saves in non-scoped mode
if (!scoped)
return "";

// Make a save file URI based on the ROM file URI
String str = file.getUri().toString();
String str = rom.getUri().toString();
Uri uri = Uri.parse(str.substring(0, str.length() - 4) + ".sav");

try
{
// Get a descriptor for the file in scoped mode
ParcelFileDescriptor desc = getContentResolver().openFileDescriptor(uri, "r");
return "/proc/self/fd/" + desc.detachFd();
return getContentResolver().openFileDescriptor(uri, "r").detachFd();
}
catch (Exception e)
{
// Create a new save file if one doesn't exist
String str2 = file.getName().toString();
DocumentFile file2 = DocumentFile.fromTreeUri(this, pathUris.get(pathUris.size() - 2));
file2.createFile("application/sav", str2.substring(0, str2.length() - 4) + ".sav");
str = rom.getName().toString();
DocumentFile save = DocumentFile.fromTreeUri(this, pathUris.get(pathUris.size() - 2));
save.createFile("application/sav", str.substring(0, str.length() - 4) + ".sav");

try
{
// Give the save an invalid size so the core treats it as new
OutputStream out = getContentResolver().openOutputStream(uri);
out.write(0xFF);
out.close();
return getRomSave(file);
return getSaveFd(rom);
}
catch (Exception e2)
{
// Oh well, I guess
return "";
return -1;
}
}
}

public static native boolean loadSettings(String rootPath);
public static native void getNdsIcon(String romPath, Bitmap bitmap);
public static native void getNdsIcon(int fd, Bitmap bitmap);
public static native int startCore();
public static native String getNdsPath();
public static native String getGbaPath();
public static native boolean isNdsLoaded();
public static native boolean isGbaLoaded();
public static native void setNdsPath(String value);
public static native void setGbaPath(String value);
public static native void setNdsSave(String value);
public static native void setGbaSave(String value);
public static native void setNdsFds(int romFd, int saveFd);
public static native void setGbaFds(int romFd, int saveFd);
}
Loading

0 comments on commit ce90e52

Please sign in to comment.