(Android) Added support for launching emulators with scoped storage permissions

This commit is contained in:
Leon Styhre 2023-11-29 22:30:22 +01:00
parent 84534cf5d7
commit 811118d3ee
4 changed files with 19 additions and 11 deletions

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition // ES-DE
// FileData.cpp // FileData.cpp
// //
// Provides game file data structures and functions to access and sort this information. // Provides game file data structures and functions to access and sort this information.
@ -951,6 +951,7 @@ void FileData::launchGame()
std::string androidPackage; std::string androidPackage;
std::string androidActivity; std::string androidActivity;
std::string androidAction; std::string androidAction;
std::string androidFileAsURI;
std::vector<std::pair<std::string, std::string>> androidExtras; std::vector<std::pair<std::string, std::string>> androidExtras;
#endif #endif
@ -1616,6 +1617,8 @@ void FileData::launchGame()
command = Utils::String::replace(command, "%ROMPATH%", command = Utils::String::replace(command, "%ROMPATH%",
Utils::FileSystem::getEscapedPath(getROMDirectory())); Utils::FileSystem::getEscapedPath(getROMDirectory()));
#if defined(__ANDROID__) #if defined(__ANDROID__)
if (command.find("%ROMURI%") != std::string::npos)
androidFileAsURI = romRaw;
command = Utils::String::replace(command, "%ANDROIDPACKAGE%", androidPackage); command = Utils::String::replace(command, "%ANDROIDPACKAGE%", androidPackage);
size_t extraPos {command.find("%EXTRA_")}; size_t extraPos {command.find("%EXTRA_")};
@ -1721,9 +1724,12 @@ void FileData::launchGame()
LOG(LogInfo) << "Package: " << androidPackage; LOG(LogInfo) << "Package: " << androidPackage;
LOG(LogInfo) << "Activity: " << (androidActivity == "" ? "<package default>" : androidActivity); LOG(LogInfo) << "Activity: " << (androidActivity == "" ? "<package default>" : androidActivity);
LOG(LogInfo) << "Action: " << (androidAction == "" ? "<package default>" : androidAction); LOG(LogInfo) << "Action: " << (androidAction == "" ? "<package default>" : androidAction);
if (androidFileAsURI != "") {
LOG(LogInfo) << "File (URI): " << androidFileAsURI;
}
for (auto& extra : androidExtras) { for (auto& extra : androidExtras) {
LOG(LogDebug) << "Extra name: " << extra.first; LOG(LogInfo) << "Extra name: " << extra.first;
LOG(LogDebug) << "Extra value: " << extra.second; LOG(LogInfo) << "Extra value: " << extra.second;
} }
#else #else
LOG(LogInfo) << "Expanded emulator launch command:"; LOG(LogInfo) << "Expanded emulator launch command:";
@ -1748,8 +1754,8 @@ void FileData::launchGame()
Utils::String::stringToWideString(command), Utils::String::stringToWideString(command),
Utils::String::stringToWideString(startDirectory), runInBackground, hideWindow); Utils::String::stringToWideString(startDirectory), runInBackground, hideWindow);
#elif defined(__ANDROID__) #elif defined(__ANDROID__)
returnValue = Utils::Platform::Android::launchGame(androidPackage, androidActivity, returnValue = Utils::Platform::Android::launchGame(
androidAction, androidExtras); androidPackage, androidActivity, androidAction, androidFileAsURI, androidExtras);
#else #else
returnValue = Utils::Platform::launchGameUnix(command, startDirectory, runInBackground); returnValue = Utils::Platform::launchGameUnix(command, startDirectory, runInBackground);
#endif #endif

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition // ES-DE
// FileData.h // FileData.h
// //
// Provides game file data structures and functions to access and sort this information. // Provides game file data structures and functions to access and sort this information.

View file

@ -403,13 +403,14 @@ namespace Utils
int launchGame(const std::string& packageName, int launchGame(const std::string& packageName,
const std::string& activity, const std::string& activity,
const std::string& action, const std::string& action,
const std::string& fileAsURI,
std::vector<std::pair<std::string, std::string>>& extras) std::vector<std::pair<std::string, std::string>>& extras)
{ {
JNIEnv* jniEnv {reinterpret_cast<JNIEnv*>(SDL_AndroidGetJNIEnv())}; JNIEnv* jniEnv {reinterpret_cast<JNIEnv*>(SDL_AndroidGetJNIEnv())};
jclass jniClass {jniEnv->FindClass("org/es_de/frontend/MainActivity")}; jclass jniClass {jniEnv->FindClass("org/es_de/frontend/MainActivity")};
jmethodID methodID { jmethodID methodID {jniEnv->GetStaticMethodID(
jniEnv->GetStaticMethodID(jniClass, "launchGame", jniClass, "launchGame",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/" "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/"
"String;Ljava/util/Vector;Ljava/util/Vector;)Z")}; "String;Ljava/util/Vector;Ljava/util/Vector;)Z")};
jclass vectorClass {jniEnv->FindClass("java/util/Vector")}; jclass vectorClass {jniEnv->FindClass("java/util/Vector")};
jmethodID vectorMID {jniEnv->GetMethodID(vectorClass, "<init>", "()V")}; jmethodID vectorMID {jniEnv->GetMethodID(vectorClass, "<init>", "()V")};
@ -426,7 +427,7 @@ namespace Utils
const bool returnValue {static_cast<bool>(jniEnv->CallStaticBooleanMethod( const bool returnValue {static_cast<bool>(jniEnv->CallStaticBooleanMethod(
jniClass, methodID, jniEnv->NewStringUTF(packageName.c_str()), jniClass, methodID, jniEnv->NewStringUTF(packageName.c_str()),
jniEnv->NewStringUTF(activity.c_str()), jniEnv->NewStringUTF(action.c_str()), jniEnv->NewStringUTF(activity.c_str()), jniEnv->NewStringUTF(action.c_str()),
extrasNames, extrasValues))}; jniEnv->NewStringUTF(fileAsURI.c_str()), extrasNames, extrasValues))};
// jniEnv->DeleteLocalRef(vectorClass); // jniEnv->DeleteLocalRef(vectorClass);
// jniEnv->DeleteLocalRef(jniClass); // jniEnv->DeleteLocalRef(jniClass);
if (returnValue) if (returnValue)

View file

@ -65,6 +65,7 @@ namespace Utils
int launchGame(const std::string& packageName, int launchGame(const std::string& packageName,
const std::string& activity, const std::string& activity,
const std::string& action, const std::string& action,
const std::string& fileAsURI,
std::vector<std::pair<std::string, std::string>>& extras); std::vector<std::pair<std::string, std::string>>& extras);
} // namespace Android } // namespace Android
#endif #endif