[Scummvm-git-logs] scummvm branch-2-7-0-android -> 8d8339bd72546bdfb5869c67e83a5f622167169c

antoniou79 noreply at scummvm.org
Thu Mar 2 12:23:36 UTC 2023


This automated email contains information about 15 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
2ee905e897 AUDIO: Add in-memory soundfont support for FluidLite
d1f0d4676e ANDROID: Allow to load soundfont through SAF
dc66a0013c ANDROID: Make sure EAS driver is open before using its functions
91621fe889 BACKENDS: NETWORKING: Set pointer to nullptr when it's deleted
1151f8dfad ANDROID: Allow to create a /saf node from path
a06dd3bb05 ANDROID: Allow SAF non-existent node creation from path
d6c0aeafcb ANDROID: Do not set global save path as launch param
afb267c83d ANDROID: Create and Register default path for icons
0283627b5c ANDROID: Factorize SAF flags computation
e4c1d5aa16 ANDROID: Add remove feature to Android filesystem abstraction
e3c52dde9c ANDROID: Don't directly use remove() for save files
9248315f64 ANDROID: Add missing header for Android filesystem specific
d8c4b3a395 ANDROID: Reserve new versionInfo batch for 2.7.0 beta 2
ab592d8e63 ANDROID: Simplify Android startup
8d8339bd72 ANDROID: Make Android onCreate more readable


Commit: 2ee905e897c32c527acd9f87f3fa3ffdd908029e
    https://github.com/scummvm/scummvm/commit/2ee905e897c32c527acd9f87f3fa3ffdd908029e
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-03-02T14:20:13+02:00

Commit Message:
AUDIO: Add in-memory soundfont support for FluidLite

Changed paths:
    audio/softsynth/fluidsynth.cpp


diff --git a/audio/softsynth/fluidsynth.cpp b/audio/softsynth/fluidsynth.cpp
index b368ffddc51..6ec5b22cf1f 100644
--- a/audio/softsynth/fluidsynth.cpp
+++ b/audio/softsynth/fluidsynth.cpp
@@ -30,6 +30,9 @@
 // prior scummsys.h inclusion and thus forbidden.h
 #ifdef USE_FLUIDLITE
 #include <fluidlite.h>
+
+#define FLUID_OK (0)
+#define FLUID_FAILED (-1)
 #else
 #include <fluidsynth.h>
 #endif
@@ -51,8 +54,11 @@
 
 // We assume here Fluidsynth minor will never be above 255 and
 // that micro versions won't break API compatibility
+// Older versions of FluidLite used FLUIDSYNTH_VERSION and now use FLUIDLITE_VERSION
 #if defined(FLUIDSYNTH_VERSION_MAJOR) && defined(FLUIDSYNTH_VERSION_MINOR)
 #define FS_API_VERSION ((FLUIDSYNTH_VERSION_MAJOR << 8) | FLUIDSYNTH_VERSION_MINOR)
+#elif defined(FLUIDLITE_VERSION_MAJOR) && defined(FLUIDLITE_VERSION_MINOR)
+#define FS_API_VERSION ((FLUIDLITE_VERSION_MAJOR << 8) | FLUIDLITE_VERSION_MINOR)
 #else
 #define FS_API_VERSION 0
 #endif
@@ -113,13 +119,7 @@ public:
 	MidiChannel *getPercussionChannel() override;
 
 	void setEngineSoundFont(Common::SeekableReadStream *soundFontData) override;
-	bool acceptsSoundFontData() override {
-#if FS_API_VERSION >= 0x0200
-		return true;
-#else
-		return false;
-#endif
-	}
+	bool acceptsSoundFontData() override;
 
 	// AudioStream API
 	bool isStereo() const override { return true; }
@@ -173,7 +173,69 @@ void MidiDriver_FluidSynth::setStr(const char *name, const char *val) {
 
 // Soundfont memory loader callback functions.
 
-#if FS_API_VERSION >= 0x0200
+#if defined(USE_FLUIDLITE) && FS_API_VERSION >= 0x0102
+
+#define FS_HAS_STREAM_SUPPORT
+
+// FluidLite calls fopen and fclose callback twice which causes a double delete
+// So, use a holder which will take care of use count
+// Luckily the open() calls are not intermixed and we don't need to maintain state
+struct fluidlite_stream_holder {
+	Common::SeekableReadStream *stream;
+	unsigned int openCounter;
+};
+
+static void *SoundFontMemLoader_open(fluid_fileapi_t *fileapi, const char *filename) {
+	fluidlite_stream_holder *holder;
+	if (filename[0] != '&') {
+		return nullptr;
+	}
+	sscanf(filename, "&%p", (void **)&holder);
+
+	// Reset the file cursor
+	holder->stream->seek(0, SEEK_SET);
+	holder->openCounter++;
+	return holder;
+}
+
+static int SoundFontMemLoader_read(void *buf, int count, void *handle) {
+	fluidlite_stream_holder *holder = (fluidlite_stream_holder *)handle;
+	return holder->stream->read(buf, count) == (uint32)count ? FLUID_OK : FLUID_FAILED;
+}
+
+static int SoundFontMemLoader_seek(void *handle, long offset, int origin) {
+	fluidlite_stream_holder *holder = (fluidlite_stream_holder *)handle;
+	return holder->stream->seek(offset, origin) ? FLUID_OK : FLUID_FAILED;
+}
+
+static int SoundFontMemLoader_close(void *handle) {
+	fluidlite_stream_holder *holder = (fluidlite_stream_holder *)handle;
+	if (!--holder->openCounter) {
+		delete holder->stream;
+		delete holder;
+	}
+	return FLUID_OK;
+}
+
+static long SoundFontMemLoader_tell(void *handle) {
+	fluidlite_stream_holder *holder = (fluidlite_stream_holder *)handle;
+	return holder->stream->pos();
+}
+
+static const fluid_fileapi_t SoundFontMemLoader_callbacks = {
+  NULL,
+  NULL,
+  SoundFontMemLoader_open,
+  SoundFontMemLoader_read,
+  SoundFontMemLoader_seek,
+  SoundFontMemLoader_close,
+  SoundFontMemLoader_tell
+};
+
+#elif FS_API_VERSION >= 0x0200
+
+#define FS_HAS_STREAM_SUPPORT
+
 static void *SoundFontMemLoader_open(const char *filename) {
 	void *p;
 	if (filename[0] != '&') {
@@ -211,7 +273,8 @@ static long SoundFontMemLoader_tell(void *handle) {
 #endif
 	return ((Common::SeekableReadStream *) handle)->pos();
 }
-#endif
+
+#endif // USE_FLUIDLITE
 
 int MidiDriver_FluidSynth::open() {
 	if (_isOpen)
@@ -223,12 +286,12 @@ int MidiDriver_FluidSynth::open() {
 	fluid_set_log_function(FLUID_INFO, logHandler, nullptr);
 	fluid_set_log_function(FLUID_DBG, logHandler, nullptr);
 
-#if FS_API_VERSION >= 0x0200
+#ifdef FS_HAS_STREAM_SUPPORT
 	// When provided with in-memory SoundFont data, only use the configured
 	// SoundFont instead if it's explicitly configured on the current game.
 	bool isUsingInMemorySoundFontData = _engineSoundFontData && !ConfMan.getActiveDomain()->contains("soundfont");
 #else
-	bool isUsingInMemorySoundFontData = false;
+	const bool isUsingInMemorySoundFontData = false;
 #endif
 
 	if (!isUsingInMemorySoundFontData && !ConfMan.hasKey("soundfont")) {
@@ -331,11 +394,22 @@ int MidiDriver_FluidSynth::open() {
 
 	fluid_synth_set_interp_method(_synth, -1, interpMethod);
 
-	const char *soundfont = !isUsingInMemorySoundFontData ?
-			ConfMan.get("soundfont").c_str() : Common::String::format("&%p", (void *)_engineSoundFontData).c_str();
+	Common::String soundfont;
 
-#if FS_API_VERSION >= 0x0200
+#if defined(FS_HAS_STREAM_SUPPORT)
 	if (isUsingInMemorySoundFontData) {
+#if defined(USE_FLUIDLITE)
+		fluidlite_stream_holder *holder = new fluidlite_stream_holder;
+		holder->stream = _engineSoundFontData;
+		holder->openCounter = 0;
+
+		fluid_sfloader_t *soundFontMemoryLoader = new_fluid_defsfloader();
+		soundFontMemoryLoader->fileapi = const_cast<fluid_fileapi_t *>(&SoundFontMemLoader_callbacks);
+		fluid_synth_add_sfloader(_synth, soundFontMemoryLoader);
+
+		soundfont = Common::String::format("&%p", (void *)holder);
+#else
+		// Fluidsynth 2.0+
 		fluid_sfloader_t *soundFontMemoryLoader = new_fluid_defsfloader(_settings);
 		fluid_sfloader_set_callbacks(soundFontMemoryLoader,
 									 SoundFontMemLoader_open,
@@ -344,27 +418,27 @@ int MidiDriver_FluidSynth::open() {
 									 SoundFontMemLoader_tell,
 									 SoundFontMemLoader_close);
 		fluid_synth_add_sfloader(_synth, soundFontMemoryLoader);
-	}
-#endif
 
+		soundfont = Common::String::format("&%p", (void *)_engineSoundFontData);
+#endif
+	} else
+#endif // FS_HAS_STREAM_SUPPORT
+	{
 #if defined(IPHONE_IOS7) && defined(IPHONE_SANDBOXED)
-	if (!isUsingInMemorySoundFontData) {
 		// HACK: Due to the sandbox on non-jailbroken iOS devices, we need to deal
 		// with the chroot filesystem. All the path selected by the user are
 		// relative to the Document directory. So, we need to adjust the path to
 		// reflect that.
-		Common::String soundfont_fullpath = iOS7_getDocumentsDir();
-		soundfont_fullpath += soundfont;
-		_soundFont = fluid_synth_sfload(_synth, soundfont_fullpath.c_str(), 1);
-	} else {
-		_soundFont = fluid_synth_sfload(_synth, soundfont, 1);
-	}
+		soundfont = iOS7_getDocumentsDir() + ConfMan.get("soundfont");
 #else
-	_soundFont = fluid_synth_sfload(_synth, soundfont, 1);
+		soundfont = ConfMan.get("soundfont");
 #endif
+	}
+
+	_soundFont = fluid_synth_sfload(_synth, soundfont.c_str(), 1);
 
 	if (_soundFont == -1) {
-		GUI::MessageDialog dialog(Common::U32String::format(_("FluidSynth: Failed loading custom SoundFont '%s'. Music is off."), soundfont));
+		GUI::MessageDialog dialog(Common::U32String::format(_("FluidSynth: Failed loading custom SoundFont '%s'. Music is off."), soundfont.c_str()));
 		dialog.runModal();
 		return MERR_DEVICE_NOT_AVAILABLE;
 	}
@@ -453,6 +527,13 @@ void MidiDriver_FluidSynth::setEngineSoundFont(Common::SeekableReadStream *sound
 	_engineSoundFontData = soundFontData;
 }
 
+bool MidiDriver_FluidSynth::acceptsSoundFontData() {
+#ifdef FS_HAS_STREAM_SUPPORT
+	return true;
+#else
+	return false;
+#endif
+}
 
 // Plugin interface
 


Commit: d1f0d4676eb756d1bf977c53199f1769fa4e38d9
    https://github.com/scummvm/scummvm/commit/d1f0d4676eb756d1bf977c53199f1769fa4e38d9
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-03-02T14:20:23+02:00

Commit Message:
ANDROID: Allow to load soundfont through SAF

Changed paths:
    audio/softsynth/fluidsynth.cpp


diff --git a/audio/softsynth/fluidsynth.cpp b/audio/softsynth/fluidsynth.cpp
index 6ec5b22cf1f..215bee4f578 100644
--- a/audio/softsynth/fluidsynth.cpp
+++ b/audio/softsynth/fluidsynth.cpp
@@ -51,6 +51,9 @@
 #if defined(IPHONE_IOS7) && defined(IPHONE_SANDBOXED)
 #include "backends/platform/ios7/ios7_common.h"
 #endif
+#ifdef __ANDROID__
+#include "backends/fs/android/android-fs-factory.h"
+#endif
 
 // We assume here Fluidsynth minor will never be above 255 and
 // that micro versions won't break API compatibility
@@ -300,6 +303,17 @@ int MidiDriver_FluidSynth::open() {
 		return MERR_DEVICE_NOT_AVAILABLE;
 	}
 
+#if defined(__ANDROID__) && defined(FS_HAS_STREAM_SUPPORT)
+	// In Android, when using SAF we need to wrap IO to make it work
+	// We can only do this with FluidSynth 2.0
+	if (!isUsingInMemorySoundFontData &&
+			AndroidFilesystemFactory::instance().hasSAF()) {
+		Common::FSNode fsnode(ConfMan.get("soundfont"));
+		_engineSoundFontData = fsnode.createReadStream();
+		isUsingInMemorySoundFontData = _engineSoundFontData != nullptr;
+	}
+#endif
+
 	_settings = new_fluid_settings();
 
 	// The default gain setting is ridiculously low - at least for me. This


Commit: dc66a0013c4c0172061958852597fafce2350f96
    https://github.com/scummvm/scummvm/commit/dc66a0013c4c0172061958852597fafce2350f96
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-03-02T14:20:31+02:00

Commit Message:
ANDROID: Make sure EAS driver is open before using its functions

This prevents crashes when the library cannot be found

Changed paths:
    audio/softsynth/eas.cpp


diff --git a/audio/softsynth/eas.cpp b/audio/softsynth/eas.cpp
index a1ca071b45f..31449ac6328 100644
--- a/audio/softsynth/eas.cpp
+++ b/audio/softsynth/eas.cpp
@@ -67,7 +67,8 @@ public:
 
 	// MidiDriver
 	int open() override;
-	bool isOpen() const override;
+	bool isOpen() const override { return _dlHandle != 0; }
+
 	void close() override;
 	void send(uint32 b) override;
 	void sysEx(const byte *msg, uint16 length) override;
@@ -313,10 +314,6 @@ int MidiDriver_EAS::open() {
 	return 0;
 }
 
-bool MidiDriver_EAS::isOpen() const {
-	return _dlHandle != 0;
-}
-
 void MidiDriver_EAS::close() {
 	MidiDriver_MPU401::close();
 
@@ -358,6 +355,9 @@ void MidiDriver_EAS::close() {
 void MidiDriver_EAS::send(uint32 b) {
 	byte buf[4];
 
+	if (!isOpen())
+		return;
+
 	WRITE_LE_UINT32(buf, b);
 
 	int32 len = 3;
@@ -372,6 +372,9 @@ void MidiDriver_EAS::send(uint32 b) {
 void MidiDriver_EAS::sysEx(const byte *msg, uint16 length) {
 	byte buf[266];
 
+	if (!isOpen())
+		return;
+
 	assert(length + 2 <= ARRAYSIZE(buf));
 
 	buf[0] = 0xF0;
@@ -397,6 +400,9 @@ int MidiDriver_EAS::readBuffer(int16 *buffer, const int numSamples) {
 	// see note at top of this file
 	assert(numSamples == INTERMEDIATE_BUFFER_SIZE);
 
+	if (!isOpen())
+		return -1;
+
 	int32 res, c;
 
 	for (uint i = 0; i < _rounds; ++i) {


Commit: 91621fe889ca5f6d3f75a624e029becafa4c6dde
    https://github.com/scummvm/scummvm/commit/91621fe889ca5f6d3f75a624e029becafa4c6dde
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-03-02T14:20:39+02:00

Commit Message:
BACKENDS: NETWORKING: Set pointer to nullptr when it's deleted

This avoids a UAF when file failed to open.

Changed paths:
    backends/networking/curl/sessionrequest.cpp


diff --git a/backends/networking/curl/sessionrequest.cpp b/backends/networking/curl/sessionrequest.cpp
index a0247480e68..0d5f145e433 100644
--- a/backends/networking/curl/sessionrequest.cpp
+++ b/backends/networking/curl/sessionrequest.cpp
@@ -58,6 +58,7 @@ void SessionRequest::openLocalFile(Common::String localFile) {
 		ErrorResponse error(this, false, true, "SessionRequestFile: unable to open file to download into", -1);
 		finishError(error);
 		delete _localFile;
+		_localFile = nullptr;
 		return;
 	}
 


Commit: 1151f8dfad8939602763b36bd6cf0b0a03766d75
    https://github.com/scummvm/scummvm/commit/1151f8dfad8939602763b36bd6cf0b0a03766d75
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-03-02T14:21:02+02:00

Commit Message:
ANDROID: Allow to create a /saf node from path

This avoids errors when creating parent directories in DumpFile
This also allows the user to specify /saf path in browser to allow
browsing.

Changed paths:
    backends/fs/android/android-fs-factory.cpp
    backends/fs/android/android-posix-fs.cpp
    backends/fs/android/android-saf-fs.cpp
    backends/fs/android/android-saf-fs.h


diff --git a/backends/fs/android/android-fs-factory.cpp b/backends/fs/android/android-fs-factory.cpp
index e478b614548..af3dcab9416 100644
--- a/backends/fs/android/android-fs-factory.cpp
+++ b/backends/fs/android/android-fs-factory.cpp
@@ -53,10 +53,14 @@ AbstractFSNode *AndroidFilesystemFactory::makeFileNodePath(const Common::String
 		return makeRootFileNode();
 	}
 
-	// No need to take SAF add mode here as it's called only for paths and we won't accept /saf path to make a new SAF
-
 	// If SAF works, it was a SAF URL
 	if (_withSAF) {
+		// Accept /saf as it can be used to create the tree in DumpFile
+		if (path == AddSAFFakeNode::SAF_ADD_FAKE_PATH) {
+			// Not a SAF mount point
+			return new AddSAFFakeNode(true);
+		}
+
 		AbstractFSNode *node = AndroidSAFFilesystemNode::makeFromPath(path);
 		if (node) {
 			return node;
@@ -90,7 +94,7 @@ void AndroidFilesystemFactory::getSAFTrees(AbstractFSList &list, bool allowSAFad
 	}
 
 	if (allowSAFadd) {
-		list.push_back(new AddSAFFakeNode());
+		list.push_back(new AddSAFFakeNode(false));
 	}
 
 }
diff --git a/backends/fs/android/android-posix-fs.cpp b/backends/fs/android/android-posix-fs.cpp
index f607c767d2b..2bc7fd4e7a9 100644
--- a/backends/fs/android/android-posix-fs.cpp
+++ b/backends/fs/android/android-posix-fs.cpp
@@ -30,13 +30,7 @@ AbstractFSNode *AndroidPOSIXFilesystemNode::makeNode() const {
 }
 
 AbstractFSNode *AndroidPOSIXFilesystemNode::makeNode(const Common::String &path) const {
-	// If SAF works, it was a SAF URL
-	AbstractFSNode *node = AndroidSAFFilesystemNode::makeFromPath(path);
-	if (node) {
-		return node;
-	}
-
-	return new AndroidPOSIXFilesystemNode(path, _config);
+	return AndroidFilesystemFactory::instance().makeFileNodePath(path);
 }
 
 #endif
diff --git a/backends/fs/android/android-saf-fs.cpp b/backends/fs/android/android-saf-fs.cpp
index b905386b5b0..0d7a0b227ac 100644
--- a/backends/fs/android/android-saf-fs.cpp
+++ b/backends/fs/android/android-saf-fs.cpp
@@ -586,6 +586,10 @@ AddSAFFakeNode::~AddSAFFakeNode() {
 }
 
 AbstractFSNode *AddSAFFakeNode::getChild(const Common::String &name) const {
+	if (_fromPath) {
+		// When starting from /saf try to get the tree node
+		return AndroidSAFFilesystemNode::makeFromPath(Common::String(AndroidSAFFilesystemNode::SAF_MOUNT_POINT) + name);
+	}
 	// We can't call getChild as it's protected
 	return nullptr;
 }
@@ -596,6 +600,11 @@ AbstractFSNode *AddSAFFakeNode::getParent() const {
 }
 
 bool AddSAFFakeNode::exists() const {
+	if (_fromPath) {
+		// /saf always exists when created as a path
+		return true;
+	}
+
 	if (!_proxied) {
 		makeProxySAF();
 	}
@@ -608,6 +617,16 @@ bool AddSAFFakeNode::exists() const {
 }
 
 bool AddSAFFakeNode::getChildren(AbstractFSList &list, ListMode mode, bool hidden) const {
+	if (_fromPath) {
+		// When built from path, /saf lists all SAF node but never proposes to add one
+		if (mode == Common::FSNode::kListFilesOnly) {
+			// All directories
+			return true;
+		}
+		AndroidFilesystemFactory::instance().getSAFTrees(list, false);
+		return true;
+	}
+
 	if (!_proxied) {
 		makeProxySAF();
 	}
@@ -620,6 +639,10 @@ bool AddSAFFakeNode::getChildren(AbstractFSList &list, ListMode mode, bool hidde
 }
 
 Common::String AddSAFFakeNode::getPath() const {
+	if (_fromPath) {
+		return SAF_ADD_FAKE_PATH;
+	}
+
 	if (!_proxied) {
 		makeProxySAF();
 	}
@@ -632,6 +655,10 @@ Common::String AddSAFFakeNode::getPath() const {
 }
 
 bool AddSAFFakeNode::isReadable() const {
+	if (_fromPath) {
+		return true;
+	}
+
 	if (!_proxied) {
 		makeProxySAF();
 	}
@@ -644,6 +671,10 @@ bool AddSAFFakeNode::isReadable() const {
 }
 
 bool AddSAFFakeNode::isWritable() const {
+	if (_fromPath) {
+		return false;
+	}
+
 	if (!_proxied) {
 		makeProxySAF();
 	}
@@ -656,6 +687,8 @@ bool AddSAFFakeNode::isWritable() const {
 }
 
 void AddSAFFakeNode::makeProxySAF() const {
+	assert(!_fromPath);
+
 	if (_proxied) {
 		return;
 	}
diff --git a/backends/fs/android/android-saf-fs.h b/backends/fs/android/android-saf-fs.h
index f6ff2690515..931c9f6b282 100644
--- a/backends/fs/android/android-saf-fs.h
+++ b/backends/fs/android/android-saf-fs.h
@@ -162,7 +162,7 @@ protected:
 public:
 	static const char SAF_ADD_FAKE_PATH[];
 
-	AddSAFFakeNode() : _proxied(nullptr) { }
+	AddSAFFakeNode(bool fromPath) : _proxied(nullptr), _fromPath(fromPath) { }
 	~AddSAFFakeNode() override;
 
 	bool exists() const override;
@@ -187,6 +187,7 @@ public:
 private:
 	void makeProxySAF() const;
 
+	bool _fromPath;
 	mutable AbstractFSNode *_proxied;
 };
 #endif


Commit: a06dd3bb05d7e57c30e8a8bc04d4c413c78da9d1
    https://github.com/scummvm/scummvm/commit/a06dd3bb05d7e57c30e8a8bc04d4c413c78da9d1
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-03-02T14:21:09+02:00

Commit Message:
ANDROID: Allow SAF non-existent node creation from path

This is used by DumpFile.
As in all other implementations, parent node is expected to exist.

Changed paths:
    backends/fs/android/android-saf-fs.cpp


diff --git a/backends/fs/android/android-saf-fs.cpp b/backends/fs/android/android-saf-fs.cpp
index 0d7a0b227ac..cfa2510794a 100644
--- a/backends/fs/android/android-saf-fs.cpp
+++ b/backends/fs/android/android-saf-fs.cpp
@@ -167,17 +167,64 @@ AndroidSAFFilesystemNode *AndroidSAFFilesystemNode::makeFromPath(const Common::S
 		return nullptr;
 	}
 
-	if (!node) {
+	if (node) {
+		AndroidSAFFilesystemNode *ret = new AndroidSAFFilesystemNode(safTree, node);
+
+		env->DeleteLocalRef(node);
+		env->DeleteLocalRef(safTree);
+
+		return ret;
+	}
+
+	// Node doesn't exist: we will try to make a node from the parent and
+	// if it works we will create a non-existent node
+
+	pos = realPath.findLastOf('/');
+	if (pos == Common::String::npos || pos == 0) {
+		// No / in path or at root, no parent and we have a tree: it's all good
+		if (pos == 0) {
+			realPath = realPath.substr(1);
+		}
+		AndroidSAFFilesystemNode *parent = makeFromTree(safTree);
+		AndroidSAFFilesystemNode *ret = static_cast<AndroidSAFFilesystemNode *>(parent->getChild(realPath));
+		delete parent;
+
+		// safTree has already been released by makeFromTree
+		return ret;
+	}
+
+	Common::String baseName(realPath.substr(pos + 1));
+	realPath.erase(pos);
+
+	pathObj = env->NewStringUTF(realPath.c_str());
+
+	node = env->CallObjectMethod(safTree, _MID_pathToNode, pathObj);
+
+	env->DeleteLocalRef(pathObj);
+
+	if (env->ExceptionCheck()) {
+		LOGE("SAFFSTree::pathToNode failed");
+
+		env->ExceptionDescribe();
+		env->ExceptionClear();
+
 		env->DeleteLocalRef(safTree);
 		return nullptr;
 	}
 
-	AndroidSAFFilesystemNode *ret = new AndroidSAFFilesystemNode(safTree, node);
+	if (node) {
+		AndroidSAFFilesystemNode *parent = new AndroidSAFFilesystemNode(safTree, node);
+		env->DeleteLocalRef(node);
+		env->DeleteLocalRef(safTree);
 
-	env->DeleteLocalRef(node);
-	env->DeleteLocalRef(safTree);
+		AndroidSAFFilesystemNode *ret = static_cast<AndroidSAFFilesystemNode *>(parent->getChild(baseName));
+		delete parent;
 
-	return ret;
+		return ret;
+	}
+
+	env->DeleteLocalRef(safTree);
+	return nullptr;
 }
 
 AndroidSAFFilesystemNode *AndroidSAFFilesystemNode::makeFromTree(jobject safTree) {


Commit: d6c0aeafcba05f56b4ca075da2820c43febe9c61
    https://github.com/scummvm/scummvm/commit/d6c0aeafcba05f56b4ca075da2820c43febe9c61
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2023-03-02T14:21:16+02:00

Commit Message:
ANDROID: Do not set global save path as launch param

Changed paths:
    backends/platform/android/android.cpp
    backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java


diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index 4958412bbcf..98320cbda46 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -450,19 +450,8 @@ void OSystem_Android::initBackend() {
 		ConfMan.setInt("gui_scale", 125); // "Large" (see gui/options.cpp and guiBaseValues[])
 	}
 
-	// BUG: "transient" ConfMan settings get nuked by the options
-	// screen. Passing the savepath in this way makes it stick
-	// (via ConfMan.registerDefault() which is called from DefaultSaveFileManager constructor (backends/saves/default/default-saves.cpp))
-	// Note: The aforementioned bug is probably the one reported here:
-	//  https://bugs.scummvm.org/ticket/3712
-	//  and maybe here:
-	//  https://bugs.scummvm.org/ticket/7389
-	// However, we do NOT set the savepath key explicitly for ConfMan
-	//          and thus the savepath will only be persisted as "default" config
-	//          for the rest of the app session (until exit).
-	//          It will NOT be reflected on the GUI, if it's not set explicitly by the user there
-	// TODO Why do we need it not shown on the GUI though?
-	//      Btw, this is a ScummVM thing, the "defaults" do not show they values on our GUI)
+
+	ConfMan.registerDefault("savepath", ConfMan.get("path") + "/saves");
 	_savefileManager = new DefaultSaveFileManager(ConfMan.get("savepath"));
 	// TODO remove the debug message eventually
 	LOGD("Setting DefaultSaveFileManager path to: %s", ConfMan.get("savepath").c_str());
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index a8b99d95db5..19f9f6ff0b8 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -79,9 +79,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 	private File _configScummvmFile;
 	private File _actualScummVMDataDir;
 	private File _possibleExternalScummVMDir;
-	private File _usingScummVMSavesDir;
 	boolean _externalPathAvailableForReadAccess;
-//	private File _usingLogFile;
 
 	// SAF related
 	public final static int REQUEST_SAF = 50000;
@@ -948,16 +946,13 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 			// Start ScummVM
 //			Log.d(ScummVM.LOG_TAG, "CONFIG: " +  _configScummvmFile.getPath());
 //			Log.d(ScummVM.LOG_TAG, "PATH: " +  _actualScummVMDataDir.getPath());
-//			Log.d(ScummVM.LOG_TAG, "LOG: " +  _usingLogFile.getPath());
-//			Log.d(ScummVM.LOG_TAG, "SAVEPATH: " +  _usingScummVMSavesDir.getPath());
 
 			// TODO log file setting via "--logfile=" + _usingLogFile.getPath() causes crash
 			//      probably because this option is specific to SDL_BACKEND (see: base/commandLine.cpp)
 			_scummvm.setArgs(new String[]{
 				"ScummVM",
 				"--config=" + _configScummvmFile.getPath(),
-				"--path=" + _actualScummVMDataDir.getPath(),
-				"--savepath=" + _usingScummVMSavesDir.getPath()
+				"--path=" + _actualScummVMDataDir.getPath()
 			});
 
 			Log.d(ScummVM.LOG_TAG, "Hover available: " + _hoverAvailable);
@@ -1400,21 +1395,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		//      to avoid issues with unavailable shared / external storage and to be (mostly) compatible with what the older versions did
 		// WARNING: The returned path may change over time if the calling app is moved to an adopted storage device, so only relative paths should be persisted.
 		_actualScummVMDataDir = getFilesDir();
-		// Checking for null only makes sense if we were using external storage
-//		if (_actualScummVMDataDir == null || !_actualScummVMDataDir.canRead()) {
-//			new AlertDialog.Builder(this)
-//				.setTitle(R.string.no_external_files_dir_access_title)
-//				.setIcon(android.R.drawable.ic_dialog_alert)
-//				.setMessage(R.string.no_external_files_dir_access)
-//				.setNegativeButton(R.string.quit,
-//					new DialogInterface.OnClickListener() {
-//						public void onClick(DialogInterface dialog, int which) {
-//							finish();
-//						}
-//					})
-//				.show();
-//			return false;
-//		}
+		// Checking for null _actualScummVMDataDir only makes sense if we were using external storage
 
 		Log.d(ScummVM.LOG_TAG, "Base ScummVM data folder is: " + _actualScummVMDataDir.getPath());
 		String smallNodeDesc;
@@ -1430,77 +1411,11 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 			}
 		}
 
-//		File internalScummVMLogsDir = new File(_actualScummVMDataDir, ".cache/scummvm/logs");
-//		if (!internalScummVMLogsDir.exists() && internalScummVMLogsDir.mkdirs()) {
-//			Log.d(ScummVM.LOG_TAG, "Created ScummVM Logs path: " + internalScummVMLogsDir.getPath());
-//		} else if (internalScummVMLogsDir.isDirectory()) {
-//			Log.d(ScummVM.LOG_TAG, "ScummVM Logs path already exists: " + internalScummVMLogsDir.getPath());
-//		} else {
-//			Log.e(ScummVM.LOG_TAG, "Could not create folder for ScummVM Logs path: " + internalScummVMLogsDir.getPath());
-//			new AlertDialog.Builder(this)
-//				.setTitle(R.string.no_log_file_title)
-//				.setIcon(android.R.drawable.ic_dialog_alert)
-//				.setMessage(R.string.no_log_file)
-//				.setNegativeButton(R.string.quit,
-//					new DialogInterface.OnClickListener() {
-//						public void onClick(DialogInterface dialog, int which) {
-//							finish();
-//						}
-//					})
-//				.show();
-//			return false;
-//		}
-//
-//		_usingLogFile = new File(internalScummVMLogsDir, "scummvm.log");
-//		try {
-//			if (_usingLogFile.exists() || !_usingLogFile.createNewFile()) {
-//				Log.d(ScummVM.LOG_TAG, "ScummVM Log file already exists!");
-//				Log.d(ScummVM.LOG_TAG, "Existing ScummVM Log: " + _usingLogFile.getPath());
-//			} else {
-//				Log.d(ScummVM.LOG_TAG, "An empty ScummVM log file was created!");
-//				Log.d(ScummVM.LOG_TAG, "New ScummVM Log: " + _usingLogFile.getPath());
-//			}
-//		} catch (Exception e) {
-//			e.printStackTrace();
-//			new AlertDialog.Builder(this)
-//				.setTitle(R.string.no_log_file_title)
-//				.setIcon(android.R.drawable.ic_dialog_alert)
-//				.setMessage(R.string.no_log_file)
-//				.setNegativeButton(R.string.quit,
-//					new DialogInterface.OnClickListener() {
-//						public void onClick(DialogInterface dialog, int which) {
-//							finish();
-//						}
-//					})
-//				.show();
-//			return false;
-//		}
-
-		File internalScummVMConfigDir = new File(_actualScummVMDataDir, ".config/scummvm");
-		if (!internalScummVMConfigDir.exists() && internalScummVMConfigDir.mkdirs()) {
-			Log.d(ScummVM.LOG_TAG, "Created ScummVM Config path: " + internalScummVMConfigDir.getPath());
-		} else if (internalScummVMConfigDir.isDirectory()) {
-			Log.d(ScummVM.LOG_TAG, "ScummVM Config path already exists: " + internalScummVMConfigDir.getPath());
-		} else {
-			Log.e(ScummVM.LOG_TAG, "Could not create folder for ScummVM Config path: " + internalScummVMConfigDir.getPath());
-			new AlertDialog.Builder(this)
-				.setTitle(R.string.no_config_file_title)
-				.setIcon(android.R.drawable.ic_dialog_alert)
-				.setMessage(R.string.no_config_file)
-				.setNegativeButton(R.string.quit,
-					new DialogInterface.OnClickListener() {
-						public void onClick(DialogInterface dialog, int which) {
-							finish();
-						}
-					})
-				.show();
-			return false;
-		}
-
 		LinkedHashMap<String, File> candidateOldLocationsOfScummVMConfigMap = new LinkedHashMap<>();
-		// Note: The "missing" case below for: (scummvm.ini)) (SDL port - A) is checked above; it is the same path we store the config file for 2.3+
+		// Note: The "missing" case below for: (scummvm.ini)) (SDL port - A) is checked above;
+		// it is the same path we store the config file for 2.3+
 		// SDL port was officially on the Play Store for versions 1.9+ up until and including 2.0)
-		// Using LinkedHashMap because the order of searching is important
+		// Using LinkedHashMap because the order of searching is important.
 		// We want to re-use the more recent ScummVM old version too
 		// TODO try getDir too without a path? just "." ??
 		candidateOldLocationsOfScummVMConfigMap.put("(scummvm.ini) (SDL port - B)", new File(_actualScummVMDataDir, "../.config/scummvm/scummvm.ini"));
@@ -1562,10 +1477,9 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		boolean existingConfigInScummVMDataDirReplacedOnce = false; // patch for 2.2.1 Beta1 purposes
 
 		// NOTE: our config file scummvm.ini is created directly inside the ScummVM internal app path
-		//       this is probably due to a mistake (?), since we do create a config path for it above
-		//       ( in File internalScummVMConfigDir , the sub-path ".config/scummvm")
-		//       However, this is harmless, so we can keep it this way.
-		//       Or we could change it in a future version.
+		//       It is more user friendly to keep it this way (rather than put it in a subpath ".config/scummvm",
+		//       since it can be directly browsable using the ScummVM's LAN server mode,
+		//       and looking in the root of the internal app folder.
 		//       Keep in mind that changing the scummvm.ini config file location would require at the very least:
 		//       - Moving the old scummvm.ini (if upgrading) to the new location and deleting it from the old one
 		//       - Updating the ScummVM documentation about the new location
@@ -1582,7 +1496,6 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 					if (tmpOldVersionFound.compareTo(maxOldVersionFound) > 0) {
 						maxOldVersionFound = tmpOldVersionFound;
 						existingVersionFoundInScummVMDataDir = tmpOldVersionFound;
-						//scummVMConfigHandled = false; // invalidate the handled flag
 					}
 				} else {
 					Log.d(ScummVM.LOG_TAG, "Could not find info on existing ScummVM version. Unsupported or corrupt file?");
@@ -1725,20 +1638,13 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		//      or external storage not always being available (but then eg. a save file on the storage should be correctly shown as not available)
 		//      or maybe among Android OS versions the same external storage could be mounted to a (somewhat) different path?
 		//      However, it seems unavoidable when user has set paths explicitly (ie not using the defaults)
-		//      We always set the default save path as a launch parameter
 		//
 		// By default choose to store savegames on app's internal storage, which is always available
 		//
 		File defaultScummVMSavesPath = new File(_actualScummVMDataDir, "saves");
-		// By default use this as the saves path
-		_usingScummVMSavesDir = new File(defaultScummVMSavesPath.getPath());
 
 		if (defaultScummVMSavesPath.exists() && defaultScummVMSavesPath.isDirectory()) {
-			try {
-				Log.d(ScummVM.LOG_TAG, "ScummVM default saves path already exists: " + defaultScummVMSavesPath.getPath());
-			} catch (Exception e) {
-				Log.d(ScummVM.LOG_TAG, "ScummVM default saves path exception CAUGHT!");
-			}
+			Log.d(ScummVM.LOG_TAG, "ScummVM default saves path already exists: " + defaultScummVMSavesPath.getPath());
 		} else if (!defaultScummVMSavesPath.exists() && defaultScummVMSavesPath.mkdirs()) {
 			Log.d(ScummVM.LOG_TAG, "Created ScummVM default saves path: " + defaultScummVMSavesPath.getPath());
 		} else {
@@ -1939,50 +1845,6 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 				}
 			}
 		}
-
-		File persistentGlobalSavePath = null;
-		if (_configScummvmFile.exists() && _configScummvmFile.isFile()) {
-			Log.d(ScummVM.LOG_TAG, "Looking into config file for save path: " + _configScummvmFile.getPath());
-			String persistentGlobalSavePathStr = getSavepathInfoFromScummvmConfiguration(_configScummvmFile.getPath());
-			if (!TextUtils.isEmpty(persistentGlobalSavePathStr) && !TextUtils.isEmpty(persistentGlobalSavePathStr.trim()) ) {
-				Log.d(ScummVM.LOG_TAG, "Found explicit save path: " + persistentGlobalSavePathStr);
-				persistentGlobalSavePath = new File(persistentGlobalSavePathStr);
-				if (persistentGlobalSavePath.exists() && persistentGlobalSavePath.isDirectory() && persistentGlobalSavePath.listFiles() != null) {
-					try {
-						Log.d(ScummVM.LOG_TAG, "ScummVM explicit saves path folder exists and it is list-able");
-					} catch (Exception e) {
-						persistentGlobalSavePath = null;
-						Log.e(ScummVM.LOG_TAG, "ScummVM explicit saves path exception CAUGHT!");
-					}
-				} else {
-					// We won't bother creating it, it's not in our scope to do that (and it would probably result in potential permission issues)
-					Log.e(ScummVM.LOG_TAG, "Could not access explicit save folder for ScummVM: " + persistentGlobalSavePath.getPath());
-					persistentGlobalSavePath = null;
-					// We should *not* quit or return here,
-					// TODO But, how do we override this explicit set path? Do we leave it to the user to reset it?
-					new AlertDialog.Builder(this)
-						.setTitle(R.string.no_save_path_title)
-						.setIcon(android.R.drawable.ic_dialog_alert)
-						.setMessage(R.string.bad_explicit_save_path_configured)
-						.setPositiveButton(R.string.ok,
-							new DialogInterface.OnClickListener() {
-								public void onClick(DialogInterface dialog, int which) {
-
-								}
-							})
-						.show();
-				}
-			} else {
-				Log.d(ScummVM.LOG_TAG, "Could not find explicit save path info in ScummVM's config file");
-			}
-		}
-
-		if (persistentGlobalSavePath != null) {
-			// Use the persistent savepath
-			_usingScummVMSavesDir = new File(persistentGlobalSavePath.getPath());
-		}
-		Log.d(ScummVM.LOG_TAG, "Resulting save path is: " + _usingScummVMSavesDir.getPath());
-
 		return true;
 	}
 


Commit: afb267c83da6b192170a0b3b2a69264d6ec19d1c
    https://github.com/scummvm/scummvm/commit/afb267c83da6b192170a0b3b2a69264d6ec19d1c
Author: Antoniou Athanasios (a.antoniou79 at gmail.com)
Date: 2023-03-02T14:21:24+02:00

Commit Message:
ANDROID: Create and Register default path for icons

Changed paths:
    backends/platform/android/android.cpp
    backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
    dists/android/res/values/strings.xml


diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index 98320cbda46..a06a5ca224f 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -456,6 +456,11 @@ void OSystem_Android::initBackend() {
 	// TODO remove the debug message eventually
 	LOGD("Setting DefaultSaveFileManager path to: %s", ConfMan.get("savepath").c_str());
 
+
+	ConfMan.registerDefault("iconspath", ConfMan.get("path") + "/icons");
+	// TODO remove the debug message eventually
+	LOGD("Setting Default Icons and Shaders path to: %s", ConfMan.get("iconspath").c_str());
+
 	_timerManager = new DefaultTimerManager();
 
 	_event_queue_lock = new Common::Mutex();
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index 19f9f6ff0b8..3f0e72461f2 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -1845,6 +1845,29 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 				}
 			}
 		}
+
+		// Also create the default directory for icons and shaders
+		File defaultScummVMIconsPath = new File(_actualScummVMDataDir, "icons");
+
+		if (defaultScummVMIconsPath.exists() && defaultScummVMIconsPath.isDirectory()) {
+			Log.d(ScummVM.LOG_TAG, "ScummVM default icons/shaders path already exists: " + defaultScummVMIconsPath.getPath());
+		} else if (!defaultScummVMIconsPath.exists() && defaultScummVMIconsPath.mkdirs()) {
+			Log.d(ScummVM.LOG_TAG, "Created ScummVM default icons/shaders path: " + defaultScummVMIconsPath.getPath());
+		} else {
+			Log.e(ScummVM.LOG_TAG, "Could not create folder for ScummVM default icons/shaders path: " + defaultScummVMIconsPath.getPath());
+			new AlertDialog.Builder(this)
+				.setTitle(R.string.no_icons_path_title)
+				.setIcon(android.R.drawable.ic_dialog_alert)
+				.setMessage(R.string.no_icons_path_configured)
+				.setNegativeButton(R.string.quit,
+					new DialogInterface.OnClickListener() {
+						public void onClick(DialogInterface dialog, int which) {
+							finish();
+						}
+					})
+				.show();
+			return false;
+		}
 		return true;
 	}
 
diff --git a/dists/android/res/values/strings.xml b/dists/android/res/values/strings.xml
index 08eb96d360a..b0e642f1aea 100644
--- a/dists/android/res/values/strings.xml
+++ b/dists/android/res/values/strings.xml
@@ -25,6 +25,8 @@
 	<string name="no_config_file">Unable to read ScummVM config file or create a new one!</string>
 	<string name="no_save_path_title">Save Path Error</string>
 	<string name="no_save_path_configured">Unable to create or access default save path!</string>
+	<string name="no_icons_path_title">Icons Path Error</string>
+	<string name="no_icons_path_configured">Unable to create or access default icons and shaders path!</string>
 	<string name="bad_explicit_save_path_configured">Unable to access the globally set save path! Please revert to default from ScummVM Options</string>
 	<!-- <string name="no_plugins_title">No plugins found</string> -->
 	<!-- <string name="no_plugins_found">ScummVM requires at least one <i>game


Commit: 0283627b5cb52eca9251e1561bd1af0d15ac184b
    https://github.com/scummvm/scummvm/commit/0283627b5cb52eca9251e1561bd1af0d15ac184b
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-03-02T14:21:31+02:00

Commit Message:
ANDROID: Factorize SAF flags computation

Changed paths:
    backends/platform/android/org/scummvm/scummvm/SAFFSTree.java


diff --git a/backends/platform/android/org/scummvm/scummvm/SAFFSTree.java b/backends/platform/android/org/scummvm/scummvm/SAFFSTree.java
index 8f22bfc2d01..298077636a0 100644
--- a/backends/platform/android/org/scummvm/scummvm/SAFFSTree.java
+++ b/backends/platform/android/org/scummvm/scummvm/SAFFSTree.java
@@ -77,9 +77,11 @@ public class SAFFSTree {
 	}
 
 	public static class SAFFSNode {
-		public static final int DIRECTORY = 1;
-		public static final int WRITABLE  = 2;
-		public static final int READABLE  = 4;
+		public static final int DIRECTORY = 0x01;
+		public static final int WRITABLE  = 0x02;
+		public static final int READABLE  = 0x04;
+		public static final int DELETABLE = 0x08;
+		public static final int REMOVABLE = 0x10;
 
 		public SAFFSNode _parent;
 		public String _path;
@@ -95,6 +97,26 @@ public class SAFFSTree {
 			_documentId = documentId;
 			_flags = flags;
 		}
+
+		private static int computeFlags(String mimeType, int flags) {
+			int ourFlags = 0;
+			if (DocumentsContract.Document.MIME_TYPE_DIR.equals(mimeType)) {
+				ourFlags |= SAFFSNode.DIRECTORY;
+			}
+			if ((flags & (DocumentsContract.Document.FLAG_SUPPORTS_WRITE | DocumentsContract.Document.FLAG_DIR_SUPPORTS_CREATE)) != 0) {
+				ourFlags |= SAFFSNode.WRITABLE;
+			}
+			if ((flags & DocumentsContract.Document.FLAG_VIRTUAL_DOCUMENT) == 0) {
+				ourFlags |= SAFFSNode.READABLE;
+			}
+			if ((flags & DocumentsContract.Document.FLAG_SUPPORTS_DELETE) != 0) {
+				ourFlags |= SAFFSNode.DELETABLE;
+			}
+			if ((flags & DocumentsContract.Document.FLAG_SUPPORTS_REMOVE) != 0) {
+				ourFlags |= SAFFSNode.REMOVABLE;
+			}
+			return ourFlags;
+		}
 	}
 
 	// Sentinel object
@@ -242,16 +264,7 @@ public class SAFFSTree {
 				final String mimeType = c.getString(2);
 				final int flags = c.getInt(3);
 
-				int ourFlags = 0;
-				if (DocumentsContract.Document.MIME_TYPE_DIR.equals(mimeType)) {
-					ourFlags |= SAFFSNode.DIRECTORY;
-				}
-				if ((flags & (DocumentsContract.Document.FLAG_SUPPORTS_WRITE | DocumentsContract.Document.FLAG_DIR_SUPPORTS_CREATE)) != 0) {
-					ourFlags |= SAFFSNode.WRITABLE;
-				}
-				if ((flags & DocumentsContract.Document.FLAG_VIRTUAL_DOCUMENT) == 0) {
-					ourFlags |= SAFFSNode.READABLE;
-				}
+				final int ourFlags = SAFFSNode.computeFlags(mimeType, flags);
 
 				SAFFSNode newnode = new SAFFSNode(node, node._path + "/" + displayName, documentId, ourFlags);
 				_cache.put(newnode._path, newnode);
@@ -300,16 +313,7 @@ public class SAFFSTree {
 
 				final int flags = c.getInt(3);
 
-				int ourFlags = 0;
-				if (DocumentsContract.Document.MIME_TYPE_DIR.equals(mimeType)) {
-					ourFlags |= SAFFSNode.DIRECTORY;
-				}
-				if ((flags & (DocumentsContract.Document.FLAG_SUPPORTS_WRITE | DocumentsContract.Document.FLAG_DIR_SUPPORTS_CREATE)) != 0) {
-					ourFlags |= SAFFSNode.WRITABLE;
-				}
-				if ((flags & DocumentsContract.Document.FLAG_VIRTUAL_DOCUMENT) == 0) {
-					ourFlags |= SAFFSNode.READABLE;
-				}
+				final int ourFlags = SAFFSNode.computeFlags(mimeType, flags);
 
 				newnode = new SAFFSNode(node, childPath, documentId, ourFlags);
 				_cache.put(newnode._path, newnode);
@@ -418,18 +422,8 @@ public class SAFFSTree {
 				final String mimeType = c.getString(1);
 				final int flags = c.getInt(2);
 
-				int ourFlags = 0;
-				if (DocumentsContract.Document.MIME_TYPE_DIR.equals(mimeType)) {
-					ourFlags |= SAFFSNode.DIRECTORY;
-				}
-				if ((flags & (DocumentsContract.Document.FLAG_SUPPORTS_WRITE | DocumentsContract.Document.FLAG_DIR_SUPPORTS_CREATE)) != 0) {
-					ourFlags |= SAFFSNode.WRITABLE;
-				}
-				if ((flags & DocumentsContract.Document.FLAG_VIRTUAL_DOCUMENT) == 0) {
-					ourFlags |= SAFFSNode.READABLE;
-				}
+				node._flags = SAFFSNode.computeFlags(mimeType, flags);
 
-				node._flags = ourFlags;
 				return displayName;
 			}
 		} catch (Exception e) {


Commit: e4c1d5aa166e2c3770c5bec2a6dcf6c4e7d8732a
    https://github.com/scummvm/scummvm/commit/e4c1d5aa166e2c3770c5bec2a6dcf6c4e7d8732a
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-03-02T14:21:38+02:00

Commit Message:
ANDROID: Add remove feature to Android filesystem abstraction

Changed paths:
    backends/fs/android/android-posix-fs.cpp
    backends/fs/android/android-posix-fs.h
    backends/fs/android/android-saf-fs.cpp
    backends/fs/android/android-saf-fs.h
    backends/platform/android/org/scummvm/scummvm/SAFFSTree.java


diff --git a/backends/fs/android/android-posix-fs.cpp b/backends/fs/android/android-posix-fs.cpp
index 2bc7fd4e7a9..a03e7f66a3d 100644
--- a/backends/fs/android/android-posix-fs.cpp
+++ b/backends/fs/android/android-posix-fs.cpp
@@ -21,6 +21,9 @@
 
 #if defined(__ANDROID__)
 
+// For remove()
+#include <stdio.h>
+
 #include "backends/fs/android/android-fs-factory.h"
 #include "backends/fs/android/android-posix-fs.h"
 #include "backends/fs/android/android-saf-fs.h"
@@ -33,4 +36,12 @@ AbstractFSNode *AndroidPOSIXFilesystemNode::makeNode(const Common::String &path)
 	return AndroidFilesystemFactory::instance().makeFileNodePath(path);
 }
 
+bool AndroidPOSIXFilesystemNode::remove() {
+	if (::remove(_path.c_str()) != 0)
+		return false;
+
+	setFlags();
+	return true;
+}
+
 #endif
diff --git a/backends/fs/android/android-posix-fs.h b/backends/fs/android/android-posix-fs.h
index c4305778e9e..4628a1e9a50 100644
--- a/backends/fs/android/android-posix-fs.h
+++ b/backends/fs/android/android-posix-fs.h
@@ -24,13 +24,17 @@
 
 #include "backends/fs/posix-drives/posix-drives-fs.h"
 
-class AndroidPOSIXFilesystemNode : public DrivePOSIXFilesystemNode {
+#include "backends/fs/android/android-fs.h"
+
+class AndroidPOSIXFilesystemNode : public DrivePOSIXFilesystemNode, public AndroidFSNode {
 	// To let the factory redefine the displayed name
 	friend class AndroidFilesystemFactory;
 protected:
 	AbstractFSNode *makeNode() const override;
 	AbstractFSNode *makeNode(const Common::String &path) const override;
 
+	bool remove() override;
+
 public:
 	AndroidPOSIXFilesystemNode(const Common::String &path, const Config &config)
 		: DrivePOSIXFilesystemNode(path, config) { }
diff --git a/backends/fs/android/android-saf-fs.cpp b/backends/fs/android/android-saf-fs.cpp
index cfa2510794a..5e29dd5b145 100644
--- a/backends/fs/android/android-saf-fs.cpp
+++ b/backends/fs/android/android-saf-fs.cpp
@@ -64,6 +64,7 @@ jmethodID AndroidSAFFilesystemNode::_MID_createDirectory = 0;
 jmethodID AndroidSAFFilesystemNode::_MID_createFile = 0;
 jmethodID AndroidSAFFilesystemNode::_MID_createReadStream = 0;
 jmethodID AndroidSAFFilesystemNode::_MID_createWriteStream = 0;
+jmethodID AndroidSAFFilesystemNode::_MID_removeNode = 0;
 jmethodID AndroidSAFFilesystemNode::_MID_removeTree = 0;
 
 jfieldID AndroidSAFFilesystemNode::_FID__treeName = 0;
@@ -107,6 +108,7 @@ void AndroidSAFFilesystemNode::initJNI() {
 	FIND_METHOD(, createFile, "(" SAFFSNodeSig "Ljava/lang/String;)" SAFFSNodeSig);
 	FIND_METHOD(, createReadStream, "(" SAFFSNodeSig ")I");
 	FIND_METHOD(, createWriteStream, "(" SAFFSNodeSig ")I");
+	FIND_METHOD(, removeNode, "(" SAFFSNodeSig ")Z");
 	FIND_METHOD(, removeTree, "()V");
 
 	FIND_FIELD(, _treeName, "Ljava/lang/String;");
@@ -542,6 +544,59 @@ bool AndroidSAFFilesystemNode::createDirectory() {
 	return true;
 }
 
+bool AndroidSAFFilesystemNode::remove() {
+	assert(_safTree != nullptr);
+
+	if (!_safNode) {
+		return false;
+	}
+
+	if (!_safParent) {
+		// It's the root of the tree: we can't delete it
+		return false;
+	}
+
+	if (isDirectory()) {
+		// Don't delete folders (yet?)
+		return false;
+	}
+
+	JNIEnv *env = JNI::getEnv();
+
+	bool result = env->CallBooleanMethod(_safTree, _MID_removeNode, _safNode);
+
+	if (env->ExceptionCheck()) {
+		LOGE("SAFFSTree::removeNode failed");
+
+		env->ExceptionDescribe();
+		env->ExceptionClear();
+
+		return false;
+	}
+
+	if (!result) {
+		return false;
+	}
+
+	env->DeleteGlobalRef(_safNode);
+	_safNode = nullptr;
+
+	// Create the parent node to fetch informations needed to make us a non-existent node
+	AndroidSAFFilesystemNode *parent = new AndroidSAFFilesystemNode(_safTree, _safParent);
+
+	size_t pos = _path.findLastOf('/');
+	if (pos == Common::String::npos) {
+		_newName = _path;
+	} else {
+		_newName = _path.substr(pos + 1);
+	}
+	_path = parent->_path;
+
+	delete parent;
+
+	return true;
+}
+
 void AndroidSAFFilesystemNode::removeTree() {
 	assert(_safParent == nullptr);
 
diff --git a/backends/fs/android/android-saf-fs.h b/backends/fs/android/android-saf-fs.h
index 931c9f6b282..53e5bbec2bf 100644
--- a/backends/fs/android/android-saf-fs.h
+++ b/backends/fs/android/android-saf-fs.h
@@ -27,12 +27,14 @@
 #include "common/translation.h"
 #include "backends/fs/abstract-fs.h"
 
+#include "backends/fs/android/android-fs.h"
+
 /**
  * Implementation of the ScummVM file system API.
  *
  * Parts of this class are documented in the base interface class, AbstractFSNode.
  */
-class AndroidSAFFilesystemNode final : public AbstractFSNode {
+class AndroidSAFFilesystemNode final : public AbstractFSNode, public AndroidFSNode {
 protected:
 	// SAFFSTree
 	static jmethodID _MID_getTreeId;
@@ -43,6 +45,7 @@ protected:
 	static jmethodID _MID_createFile;
 	static jmethodID _MID_createReadStream;
 	static jmethodID _MID_createWriteStream;
+	static jmethodID _MID_removeNode;
 	static jmethodID _MID_removeTree;
 
 	static jfieldID _FID__treeName;
@@ -134,6 +137,8 @@ public:
 	Common::SeekableWriteStream *createWriteStream() override;
 	bool createDirectory() override;
 
+	bool remove() override;
+
 	/**
 	 * Removes the SAF tree.
 	 * Only works on the root node
@@ -154,7 +159,7 @@ protected:
 	void cacheData(bool force = false);
 };
 
-class AddSAFFakeNode final : public AbstractFSNode {
+class AddSAFFakeNode final : public AbstractFSNode, public AndroidFSNode {
 protected:
 	AbstractFSNode *getChild(const Common::String &name) const override;
 	AbstractFSNode *getParent() const override;
@@ -178,11 +183,11 @@ public:
 	bool isReadable() const override;
 	bool isWritable() const override;
 
-
 	Common::SeekableReadStream *createReadStream() override { return nullptr; }
-	virtual Common::SeekableWriteStream *createWriteStream() override { return nullptr; }
+	Common::SeekableWriteStream *createWriteStream() override { return nullptr; }
 
-	virtual bool createDirectory() { return false; }
+	bool createDirectory() override { return false; }
+	bool remove() override { return false; }
 
 private:
 	void makeProxySAF() const;
diff --git a/backends/platform/android/org/scummvm/scummvm/SAFFSTree.java b/backends/platform/android/org/scummvm/scummvm/SAFFSTree.java
index 298077636a0..8ea88ce4547 100644
--- a/backends/platform/android/org/scummvm/scummvm/SAFFSTree.java
+++ b/backends/platform/android/org/scummvm/scummvm/SAFFSTree.java
@@ -347,6 +347,40 @@ public class SAFFSTree {
 		return createStream(node, "wt");
 	}
 
+	public boolean removeNode(SAFFSNode node) {
+		final ContentResolver resolver = _context.getContentResolver();
+		final Uri uri = DocumentsContract.buildDocumentUriUsingTree(_treeUri, node._documentId);
+
+		if ((node._flags & SAFFSNode.REMOVABLE) != 0) {
+			final Uri parentUri = DocumentsContract.buildDocumentUriUsingTree(_treeUri, node._parent._documentId);
+			try {
+				if (!DocumentsContract.removeDocument(resolver, uri, parentUri)) {
+					return false;
+				}
+			} catch(FileNotFoundException e) {
+				return false;
+			}
+		} else if ((node._flags & SAFFSNode.DELETABLE) != 0) {
+			try {
+				if (!DocumentsContract.deleteDocument(resolver, uri)) {
+					return false;
+				}
+			} catch(FileNotFoundException e) {
+				return false;
+			}
+		} else {
+			return false;
+		}
+
+		for(Map.Entry<String, SAFFSNode> e : _cache.entrySet()) {
+			if (e.getValue() == node) {
+				e.setValue(NOT_FOUND_NODE);
+			}
+		}
+
+		return true;
+	}
+
 	public void removeTree() {
 		final ContentResolver resolver = _context.getContentResolver();
 


Commit: e3c52dde9c40fa820daa532241787c91d69e4831
    https://github.com/scummvm/scummvm/commit/e3c52dde9c40fa820daa532241787c91d69e4831
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-03-02T14:21:45+02:00

Commit Message:
ANDROID: Don't directly use remove() for save files

Use our brand new remove feature in filesystem

Changed paths:
    backends/platform/android/android.cpp


diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index a06a5ca224f..4f21d14140b 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -70,6 +70,7 @@
 #include "backends/graphics3d/android/android-graphics3d.h"
 #include "backends/platform/android/jni-android.h"
 #include "backends/platform/android/android.h"
+#include "backends/fs/android/android-fs.h"
 #include "backends/fs/android/android-fs-factory.h"
 
 const char *android_log_tag = "ScummVM";
@@ -122,6 +123,38 @@ void checkGlError(const char *expr, const char *file, int line) {
 }
 #endif
 
+class AndroidSaveFileManager : public DefaultSaveFileManager {
+public:
+	AndroidSaveFileManager(const Common::String &defaultSavepath) : DefaultSaveFileManager(defaultSavepath) {}
+
+	bool removeSavefile(const Common::String &filename) override {
+		Common::String path = getSavePath() + "/" + filename;
+		AbstractFSNode *node = AndroidFilesystemFactory::instance().makeFileNodePath(path);
+
+		if (!node) {
+			return false;
+		}
+
+		AndroidFSNode *anode = dynamic_cast<AndroidFSNode *>(node);
+
+		if (!anode) {
+			// This should never happen
+			warning("Invalid node received");
+			delete node;
+			return false;
+		}
+
+		bool ret = anode->remove();
+
+		delete anode;
+
+		if (!ret) {
+			setError(Common::kUnknownError, Common::String("Couldn't delete the save file: %s", path.c_str()));
+		}
+		return ret;
+	}
+};
+
 OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) :
 	_audio_sample_rate(audio_sample_rate),
 	_audio_buffer_size(audio_buffer_size),
@@ -450,9 +483,7 @@ void OSystem_Android::initBackend() {
 		ConfMan.setInt("gui_scale", 125); // "Large" (see gui/options.cpp and guiBaseValues[])
 	}
 
-
-	ConfMan.registerDefault("savepath", ConfMan.get("path") + "/saves");
-	_savefileManager = new DefaultSaveFileManager(ConfMan.get("savepath"));
+	_savefileManager = new AndroidSaveFileManager(ConfMan.get("path") + "/saves");
 	// TODO remove the debug message eventually
 	LOGD("Setting DefaultSaveFileManager path to: %s", ConfMan.get("savepath").c_str());
 


Commit: 9248315f6447abd911228bfe50d3b059f2b08fab
    https://github.com/scummvm/scummvm/commit/9248315f6447abd911228bfe50d3b059f2b08fab
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-03-02T14:21:52+02:00

Commit Message:
ANDROID: Add missing header for Android filesystem specific

Changed paths:
  A backends/fs/android/android-fs.h


diff --git a/backends/fs/android/android-fs.h b/backends/fs/android/android-fs.h
new file mode 100644
index 00000000000..1e88c74ffb6
--- /dev/null
+++ b/backends/fs/android/android-fs.h
@@ -0,0 +1,35 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef ANDROID_FILESYSTEM_H
+#define ANDROID_FILESYSTEM_H
+
+/**
+ * Common interface for Android filesystem types: SAF and POSIX
+ * Currently, only a remove function to delete files.
+ */
+class AndroidFSNode {
+public:
+	virtual ~AndroidFSNode() {}
+	virtual bool remove() = 0;
+};
+
+#endif


Commit: d8c4b3a395d434e3249abf363e9754731bde10b0
    https://github.com/scummvm/scummvm/commit/d8c4b3a395d434e3249abf363e9754731bde10b0
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2023-03-02T14:21:58+02:00

Commit Message:
ANDROID: Reserve new versionInfo batch for 2.7.0 beta 2

Changed paths:
    dists/android/build.gradle


diff --git a/dists/android/build.gradle b/dists/android/build.gradle
index 1bd631e3cc5..1a8f83f5245 100644
--- a/dists/android/build.gradle
+++ b/dists/android/build.gradle
@@ -39,10 +39,11 @@ android {
         targetSdkVersion 33
 
         versionName "2.7.0"
-        versionCode 89
+        versionCode 93
         // versioncode must be incremented for each market upload
-        // ScummVM 2.7.0: 89-92 (arm-v7a, arm64-v8a, x86, x86_64 respectively)
+        // ScummVM 2.7.0: 93-96 (arm-v7a, arm64-v8a, x86, x86_64 respectively) (beta 2 on Play Store)
         // Historical version codes:
+        // ScummVM 2.7.0: 89-92 (arm-v7a, arm64-v8a, x86, x86_64 respectively) (beta 1 on Play Store)
         // ScummVM 2.6.x: 85-88 (skipped - was reserved for potential beta or 2.6.x bugfix builds)
         // ScummVM 2.6.x: 81-84 (skipped - was reserved for potential beta or 2.6.x bugfix builds)
         // ScummVM 2.6.1: 77-80 (arm-v7a, arm64-v8a, x86, x86_64 respectively)


Commit: ab592d8e6304505703ef45f36ffe80273dcf5a4e
    https://github.com/scummvm/scummvm/commit/ab592d8e6304505703ef45f36ffe80273dcf5a4e
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-03-02T14:22:06+02:00

Commit Message:
ANDROID: Simplify Android startup

Do not pass arguments to the process but customize the backend instead

Changed paths:
    backends/platform/android/android.cpp
    backends/platform/android/android.h
    backends/platform/android/jni-android.cpp
    backends/platform/android/jni-android.h
    backends/platform/android/org/scummvm/scummvm/ScummVM.java
    backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java


diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index 4f21d14140b..c1ad7d86018 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -483,12 +483,14 @@ void OSystem_Android::initBackend() {
 		ConfMan.setInt("gui_scale", 125); // "Large" (see gui/options.cpp and guiBaseValues[])
 	}
 
-	_savefileManager = new AndroidSaveFileManager(ConfMan.get("path") + "/saves");
+	Common::String basePath = JNI::getScummVMBasePath();
+
+	_savefileManager = new AndroidSaveFileManager(basePath + "/saves");
 	// TODO remove the debug message eventually
 	LOGD("Setting DefaultSaveFileManager path to: %s", ConfMan.get("savepath").c_str());
 
 
-	ConfMan.registerDefault("iconspath", ConfMan.get("path") + "/icons");
+	ConfMan.registerDefault("iconspath", basePath + "/icons");
 	// TODO remove the debug message eventually
 	LOGD("Setting Default Icons and Shaders path to: %s", ConfMan.get("iconspath").c_str());
 
@@ -524,6 +526,10 @@ void OSystem_Android::initBackend() {
 	BaseBackend::initBackend();
 }
 
+Common::String OSystem_Android::getDefaultConfigFileName() {
+	return JNI::getScummVMConfigPath();
+}
+
 bool OSystem_Android::hasFeature(Feature f) {
 	if (f == kFeatureFullscreenMode)
 		return false;
diff --git a/backends/platform/android/android.h b/backends/platform/android/android.h
index 432caa3e61d..f980bd0ac08 100644
--- a/backends/platform/android/android.h
+++ b/backends/platform/android/android.h
@@ -173,6 +173,8 @@ public:
 	Common::KeymapArray getGlobalKeymaps() override;
 	Common::KeymapperDefaultBindings *getKeymapperDefaultBindings() override;
 
+	Common::String getDefaultConfigFileName() override;
+
 	void registerDefaultSettings(const Common::String &target) const override;
 	GUI::OptionsContainerWidget *buildBackendOptionsWidget(GUI::GuiObject *boss, const Common::String &name, const Common::String &target) const override;
 	void applyBackendSettings() override;
diff --git a/backends/platform/android/jni-android.cpp b/backends/platform/android/jni-android.cpp
index 8893e688633..f87baaf0ca0 100644
--- a/backends/platform/android/jni-android.cpp
+++ b/backends/platform/android/jni-android.cpp
@@ -92,6 +92,8 @@ jmethodID JNI::_MID_showKeyboardControl = 0;
 jmethodID JNI::_MID_getBitmapResource = 0;
 jmethodID JNI::_MID_setTouchMode = 0;
 jmethodID JNI::_MID_getTouchMode = 0;
+jmethodID JNI::_MID_getScummVMBasePath;
+jmethodID JNI::_MID_getScummVMConfigPath;
 jmethodID JNI::_MID_getSysArchives = 0;
 jmethodID JNI::_MID_getAllStorageLocations = 0;
 jmethodID JNI::_MID_initSurface = 0;
@@ -503,9 +505,60 @@ int JNI::getTouchMode() {
 	return mode;
 }
 
+Common::String JNI::getScummVMBasePath() {
+	JNIEnv *env = JNI::getEnv();
+
+	jstring pathObj = (jstring)env->CallObjectMethod(_jobj, _MID_getScummVMBasePath);
+
+	if (env->ExceptionCheck()) {
+		LOGE("Failed to get ScummVM base path");
+
+		env->ExceptionDescribe();
+		env->ExceptionClear();
+
+		return Common::String();
+	}
+
+	Common::String path;
+	const char *pathP = env->GetStringUTFChars(pathObj, 0);
+	if (pathP != 0) {
+		path = Common::String(pathP);
+		env->ReleaseStringUTFChars(pathObj, pathP);
+	}
+	env->DeleteLocalRef(pathObj);
+
+	return path;
+}
+
+Common::String JNI::getScummVMConfigPath() {
+	JNIEnv *env = JNI::getEnv();
+
+	jstring pathObj = (jstring)env->CallObjectMethod(_jobj, _MID_getScummVMConfigPath);
+
+	if (env->ExceptionCheck()) {
+		LOGE("Failed to get ScummVM base path");
+
+		env->ExceptionDescribe();
+		env->ExceptionClear();
+
+		return Common::String();
+	}
+
+	Common::String path;
+	const char *pathP = env->GetStringUTFChars(pathObj, 0);
+	if (pathP != 0) {
+		path = Common::String(pathP);
+		env->ReleaseStringUTFChars(pathObj, pathP);
+	}
+	env->DeleteLocalRef(pathObj);
+
+	return path;
+}
+
+
 // The following adds assets folder to search set.
 // However searching and retrieving from "assets" on Android this is slow
-// so we also make sure to add the "path" directory, with a higher priority
+// so we also make sure to add the base directory, with a higher priority
 // This is done via a call to ScummVMActivity's (java) getSysArchives
 void JNI::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
 	JNIEnv *env = JNI::getEnv();
@@ -672,6 +725,8 @@ void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
 	FIND_METHOD(, getBitmapResource, "(I)Landroid/graphics/Bitmap;");
 	FIND_METHOD(, setTouchMode, "(I)V");
 	FIND_METHOD(, getTouchMode, "()I");
+	FIND_METHOD(, getScummVMBasePath, "()Ljava/lang/String;");
+	FIND_METHOD(, getScummVMConfigPath, "()Ljava/lang/String;");
 	FIND_METHOD(, getSysArchives, "()[Ljava/lang/String;");
 	FIND_METHOD(, getAllStorageLocations, "()[Ljava/lang/String;");
 	FIND_METHOD(, initSurface, "()Ljavax/microedition/khronos/egl/EGLSurface;");
diff --git a/backends/platform/android/jni-android.h b/backends/platform/android/jni-android.h
index 3f3d75d9a68..00719e5f40e 100644
--- a/backends/platform/android/jni-android.h
+++ b/backends/platform/android/jni-android.h
@@ -88,6 +88,8 @@ public:
 	static void setTouchMode(int touchMode);
 	static int getTouchMode();
 	static void addSysArchivesToSearchSet(Common::SearchSet &s, int priority);
+	static Common::String getScummVMBasePath();
+	static Common::String getScummVMConfigPath();
 	static jint getAndroidSDKVersionId();
 
 	static inline bool haveSurface();
@@ -137,6 +139,8 @@ private:
 	static jmethodID _MID_getBitmapResource;
 	static jmethodID _MID_setTouchMode;
 	static jmethodID _MID_getTouchMode;
+	static jmethodID _MID_getScummVMBasePath;
+	static jmethodID _MID_getScummVMConfigPath;
 	static jmethodID _MID_getSysArchives;
 	static jmethodID _MID_getAllStorageLocations;
 	static jmethodID _MID_initSurface;
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVM.java b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
index ba990998cff..0c2064917bf 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVM.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
@@ -77,6 +77,8 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
 	abstract protected Bitmap getBitmapResource(int resource);
 	abstract protected void setTouchMode(int touchMode);
 	abstract protected int getTouchMode();
+	abstract protected String getScummVMBasePath();
+	abstract protected String getScummVMConfigPath();
 	abstract protected String[] getSysArchives();
 	abstract protected String[] getAllStorageLocations();
 	abstract protected String[] getAllStorageLocationsNoPermissionRequest();
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index 3f0e72461f2..18cda047260 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -778,6 +778,16 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 			return _events.getTouchMode();
 		}
 
+		@Override
+		protected String getScummVMBasePath() {
+			return _actualScummVMDataDir.getPath();
+		}
+
+		@Override
+		protected String getScummVMConfigPath() {
+			return _configScummvmFile.getPath();
+		}
+
 		@Override
 		protected String[] getSysArchives() {
 			Log.d(ScummVM.LOG_TAG, "Adding to Search Archive: " + _actualScummVMDataDir.getPath());
@@ -944,15 +954,8 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 			// We should have a valid path to a configuration file here
 
 			// Start ScummVM
-//			Log.d(ScummVM.LOG_TAG, "CONFIG: " +  _configScummvmFile.getPath());
-//			Log.d(ScummVM.LOG_TAG, "PATH: " +  _actualScummVMDataDir.getPath());
-
-			// TODO log file setting via "--logfile=" + _usingLogFile.getPath() causes crash
-			//      probably because this option is specific to SDL_BACKEND (see: base/commandLine.cpp)
 			_scummvm.setArgs(new String[]{
-				"ScummVM",
-				"--config=" + _configScummvmFile.getPath(),
-				"--path=" + _actualScummVMDataDir.getPath()
+				"ScummVM"
 			});
 
 			Log.d(ScummVM.LOG_TAG, "Hover available: " + _hoverAvailable);


Commit: 8d8339bd72546bdfb5869c67e83a5f622167169c
    https://github.com/scummvm/scummvm/commit/8d8339bd72546bdfb5869c67e83a5f622167169c
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-03-02T14:22:14+02:00

Commit Message:
ANDROID: Make Android onCreate more readable

The else clause was not necessary.

Changed paths:
    backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java


diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index 18cda047260..4ecdd043558 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -950,47 +950,48 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		if (!seekAndInitScummvmConfiguration()) {
 			Log.e(ScummVM.LOG_TAG, "Error while trying to find and/or initialize ScummVM configuration file!");
 			// in fact in all the cases where we return false, we also called finish()
-		} else {
-			// We should have a valid path to a configuration file here
+			return;
+		}
 
-			// Start ScummVM
-			_scummvm.setArgs(new String[]{
-				"ScummVM"
-			});
+		// We should have a valid path to a configuration file here
 
-			Log.d(ScummVM.LOG_TAG, "Hover available: " + _hoverAvailable);
-			_mouseHelper = null;
-			if (_hoverAvailable) {
-				_mouseHelper = new MouseHelper(_scummvm);
-//				_mouseHelper.attach(_main_surface);
-			}
+		// Start ScummVM
+		_scummvm.setArgs(new String[]{
+			"ScummVM"
+		});
 
-			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
-				_events = new ScummVMEventsModern(this, _scummvm, _mouseHelper);
-			} else {
-				_events = new ScummVMEventsBase(this, _scummvm, _mouseHelper);
-			}
+		Log.d(ScummVM.LOG_TAG, "Hover available: " + _hoverAvailable);
+		_mouseHelper = null;
+		if (_hoverAvailable) {
+			_mouseHelper = new MouseHelper(_scummvm);
+			//_mouseHelper.attach(_main_surface);
+		}
 
-			setupTouchModeBtn(_events.getTouchMode());
+		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
+			_events = new ScummVMEventsModern(this, _scummvm, _mouseHelper);
+		} else {
+			_events = new ScummVMEventsBase(this, _scummvm, _mouseHelper);
+		}
 
-			// On screen button listener
-			//findViewById(R.id.show_keyboard).setOnClickListener(keyboardBtnOnClickListener);
-			_toggleTouchModeKeyboardBtnIcon.setOnClickListener(touchModeKeyboardBtnOnClickListener);
-			_toggleTouchModeKeyboardBtnIcon.setOnLongClickListener(touchModeKeyboardBtnOnLongClickListener);
-			_openMenuBtnIcon.setOnClickListener(menuBtnOnClickListener);
+		setupTouchModeBtn(_events.getTouchMode());
 
-			// Keyboard visibility listener - mainly to hide system UI if keyboard is shown and we return from Suspend to the Activity
-			setKeyboardVisibilityListener(this);
+		// On screen button listener
+		//findViewById(R.id.show_keyboard).setOnClickListener(keyboardBtnOnClickListener);
+		_toggleTouchModeKeyboardBtnIcon.setOnClickListener(touchModeKeyboardBtnOnClickListener);
+		_toggleTouchModeKeyboardBtnIcon.setOnLongClickListener(touchModeKeyboardBtnOnLongClickListener);
+		_openMenuBtnIcon.setOnClickListener(menuBtnOnClickListener);
 
-			_main_surface.setOnKeyListener(_events);
-			_main_surface.setOnTouchListener(_events);
-			if (_mouseHelper != null) {
-				_main_surface.setOnHoverListener(_mouseHelper);
-			}
+		// Keyboard visibility listener - mainly to hide system UI if keyboard is shown and we return from Suspend to the Activity
+		setKeyboardVisibilityListener(this);
 
-			_scummvm_thread = new Thread(_scummvm, "ScummVM");
-			_scummvm_thread.start();
+		_main_surface.setOnKeyListener(_events);
+		_main_surface.setOnTouchListener(_events);
+		if (_mouseHelper != null) {
+			_main_surface.setOnHoverListener(_mouseHelper);
 		}
+
+		_scummvm_thread = new Thread(_scummvm, "ScummVM");
+		_scummvm_thread.start();
 	}
 
 	@Override




More information about the Scummvm-git-logs mailing list