(Android) Added support for defining a specific Intent action in the find rule configuration

This commit is contained in:
Leon Styhre 2023-11-26 22:19:24 +01:00
parent 310fb6e809
commit 25f017d9f8
3 changed files with 69 additions and 34 deletions

View file

@ -949,7 +949,8 @@ void FileData::launchGame()
#if defined(__ANDROID__) #if defined(__ANDROID__)
std::string androidPackage; std::string androidPackage;
std::string androidComponent; std::string androidActivity;
std::string androidAction;
std::vector<std::pair<std::string, std::string>> androidExtras; std::vector<std::pair<std::string, std::string>> androidExtras;
#endif #endif
@ -1110,13 +1111,27 @@ void FileData::launchGame()
#if defined(__ANDROID__) #if defined(__ANDROID__)
else if (emulator.second == FileData::findEmulatorResult::FOUND_ANDROID_PACKAGE) { else if (emulator.second == FileData::findEmulatorResult::FOUND_ANDROID_PACKAGE) {
androidPackage = emulator.first; androidPackage = emulator.first;
const size_t pipePos {androidPackage.find('|')}; size_t separatorPos {androidPackage.find('/')};
if (pipePos != std::string::npos) {
androidComponent = androidPackage.substr(pipePos + 1); if (separatorPos != std::string::npos) {
androidPackage = androidPackage.substr(0, pipePos); androidActivity = androidPackage.substr(separatorPos + 1);
androidPackage = androidPackage.substr(0, separatorPos);
} }
LOG(LogDebug) << "FileData::launchGame(): Found Android emulator package \""
<< androidPackage << "\""; separatorPos = androidPackage.find('|');
if (separatorPos != std::string::npos) {
androidAction = androidPackage.substr(separatorPos + 1);
androidPackage = androidPackage.substr(0, separatorPos);
}
separatorPos = androidActivity.find('|');
if (separatorPos != std::string::npos) {
androidAction = androidActivity.substr(separatorPos + 1);
androidActivity = androidActivity.substr(0, separatorPos);
}
LOG(LogDebug) << "FileData::launchGame(): Found emulator package \"" << androidPackage
<< "\"";
} }
#endif #endif
else if (!isShortcut) { else if (!isShortcut) {
@ -1702,13 +1717,13 @@ void FileData::launchGame()
LOG(LogDebug) << "Raw emulator launch command:"; LOG(LogDebug) << "Raw emulator launch command:";
LOG(LogDebug) << commandRaw; LOG(LogDebug) << commandRaw;
#if defined(__ANDROID__) #if defined(__ANDROID__)
LOG(LogInfo) << "Expanded emulator launch parameters:"; LOG(LogInfo) << "Expanded emulator launch arguments:";
LOG(LogInfo) << "Package: " << androidPackage; LOG(LogInfo) << "Package: " << androidPackage;
LOG(LogInfo) << "Component: " LOG(LogInfo) << "Activity: " << (androidActivity == "" ? "<package default>" : androidActivity);
<< (androidComponent == "" ? "<package default>" : androidComponent); LOG(LogInfo) << "Action: " << (androidAction == "" ? "<package default>" : androidAction);
for (auto& extra : androidExtras) { for (auto& extra : androidExtras) {
LOG(LogInfo) << "Extra name: " << extra.first; LOG(LogDebug) << "Extra name: " << extra.first;
LOG(LogInfo) << "Extra value: " << extra.second; LOG(LogDebug) << "Extra value: " << extra.second;
} }
#else #else
LOG(LogInfo) << "Expanded emulator launch command:"; LOG(LogInfo) << "Expanded emulator launch command:";
@ -1733,8 +1748,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 = returnValue = Utils::Platform::Android::launchGame(androidPackage, androidActivity,
Utils::Platform::Android::launchGame(androidPackage, androidComponent, androidExtras); androidAction, androidExtras);
#else #else
returnValue = Utils::Platform::launchGameUnix(command, startDirectory, runInBackground); returnValue = Utils::Platform::launchGameUnix(command, startDirectory, runInBackground);
#endif #endif
@ -2028,18 +2043,35 @@ const std::pair<std::string, FileData::findEmulatorResult> FileData::findEmulato
#if defined(__ANDROID__) #if defined(__ANDROID__)
for (std::string& androidpackage : emulatorAndroidPackages) { for (std::string& androidpackage : emulatorAndroidPackages) {
// If a pipe character is present in the androidpackage entry it means an explicit Intent // If a forward slash character is present in the androidpackage entry it means an explicit
// component should be used rather than the default one. The checkEmulatorInstalled() // Intent activity should be used rather than the default one. The checkEmulatorInstalled()
// Java function will check for the component as well and if it's not found it flags // Java function will check for the activity as well and if it's not found it flags
// the overall emulator entry as not found. // the overall emulator entry as not found. It's also possible to define an explicit
// Intent action using the pipe character but this is not checked for in the Java
// function as invalid actions will not lead to crashes.
std::string packageName {androidpackage}; std::string packageName {androidpackage};
std::string component; std::string activity;
const size_t pipePos {packageName.find('|')}; std::string action;
if (pipePos != std::string::npos) { size_t separatorPos {packageName.find('/')};
component = packageName.substr(pipePos + 1);
packageName = packageName.substr(0, pipePos); if (separatorPos != std::string::npos) {
activity = packageName.substr(separatorPos + 1);
packageName = packageName.substr(0, separatorPos);
} }
if (Utils::Platform::Android::checkEmulatorInstalled(packageName, component)) {
separatorPos = packageName.find('|');
if (separatorPos != std::string::npos) {
action = packageName.substr(separatorPos + 1);
packageName = packageName.substr(0, separatorPos);
}
separatorPos = activity.find('|');
if (separatorPos != std::string::npos) {
action = activity.substr(separatorPos + 1);
activity = activity.substr(0, separatorPos);
}
if (Utils::Platform::Android::checkEmulatorInstalled(packageName, activity)) {
return std::make_pair(androidpackage, return std::make_pair(androidpackage,
FileData::findEmulatorResult::FOUND_ANDROID_PACKAGE); FileData::findEmulatorResult::FOUND_ANDROID_PACKAGE);
} }

View file

@ -387,8 +387,7 @@ namespace Utils
return result; return result;
} }
bool checkEmulatorInstalled(const std::string& packageName, bool checkEmulatorInstalled(const std::string& packageName, const std::string& activity)
const std::string& component)
{ {
JNIEnv* jniEnv {reinterpret_cast<JNIEnv*>(SDL_AndroidGetJNIEnv())}; JNIEnv* jniEnv {reinterpret_cast<JNIEnv*>(SDL_AndroidGetJNIEnv())};
jclass jniClass {jniEnv->FindClass("org/esde/esde/esde")}; jclass jniClass {jniEnv->FindClass("org/esde/esde/esde")};
@ -396,20 +395,22 @@ namespace Utils
jniClass, "checkEmulatorInstalled", "(Ljava/lang/String;Ljava/lang/String;)Z")}; jniClass, "checkEmulatorInstalled", "(Ljava/lang/String;Ljava/lang/String;)Z")};
bool returnValue {static_cast<bool>(jniEnv->CallStaticBooleanMethod( bool returnValue {static_cast<bool>(jniEnv->CallStaticBooleanMethod(
jniClass, methodID, jniEnv->NewStringUTF(packageName.c_str()), jniClass, methodID, jniEnv->NewStringUTF(packageName.c_str()),
jniEnv->NewStringUTF(component.c_str())))}; jniEnv->NewStringUTF(activity.c_str())))};
// jniEnv->DeleteLocalRef(jniClass); // jniEnv->DeleteLocalRef(jniClass);
return returnValue; return returnValue;
} }
int launchGame(const std::string& packageName, int launchGame(const std::string& packageName,
const std::string& component, const std::string& activity,
const std::string& action,
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/esde/esde/esde")}; jclass jniClass {jniEnv->FindClass("org/esde/esde/esde")};
jmethodID methodID {jniEnv->GetStaticMethodID( jmethodID methodID {
jniClass, "launchGame", jniEnv->GetStaticMethodID(jniClass, "launchGame",
"(Ljava/lang/String;Ljava/lang/String;Ljava/util/Vector;Ljava/util/Vector;)Z")}; "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/"
"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")};
jmethodID addMethodID { jmethodID addMethodID {
@ -424,7 +425,8 @@ 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(component.c_str()), extrasNames, extrasValues))}; jniEnv->NewStringUTF(activity.c_str()), jniEnv->NewStringUTF(action.c_str()),
extrasNames, extrasValues))};
// jniEnv->DeleteLocalRef(vectorClass); // jniEnv->DeleteLocalRef(vectorClass);
// jniEnv->DeleteLocalRef(jniClass); // jniEnv->DeleteLocalRef(jniClass);
if (returnValue) if (returnValue)

View file

@ -61,9 +61,10 @@ namespace Utils
{ {
bool requestStoragePermission(); bool requestStoragePermission();
bool checkEmulatorInstalled(const std::string& packageName, bool checkEmulatorInstalled(const std::string& packageName,
const std::string& component); const std::string& activity);
int launchGame(const std::string& packageName, int launchGame(const std::string& packageName,
const std::string& component, const std::string& activity,
const std::string& action,
std::vector<std::pair<std::string, std::string>>& extras); std::vector<std::pair<std::string, std::string>>& extras);
} // namespace Android } // namespace Android
#endif #endif