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

View file

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

View file

@ -61,9 +61,10 @@ namespace Utils
{
bool requestStoragePermission();
bool checkEmulatorInstalled(const std::string& packageName,
const std::string& component);
const std::string& activity);
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);
} // namespace Android
#endif