ANDROID: Allow to use an Intent to start a specific game

UI to create such intents will come in a later commit.
If the game is already running, it's resumed where it was left when
ScummVM was paused.
This commit is contained in:
Le Philousophe 2024-05-16 08:08:13 +02:00
parent 074344f84e
commit 4ecf2e4ccc
6 changed files with 115 additions and 6 deletions

View File

@ -575,11 +575,13 @@ void OSystem_Android::engineInit() {
_engineRunning = true;
updateOnScreenControls();
JNI::setCurrentGame(ConfMan.getActiveDomainName());
}
void OSystem_Android::engineDone() {
_engineRunning = false;
updateOnScreenControls();
JNI::setCurrentGame("");
}
void OSystem_Android::updateOnScreenControls() {

View File

@ -98,6 +98,7 @@ jmethodID JNI::_MID_setOrientation = 0;
jmethodID JNI::_MID_getScummVMBasePath;
jmethodID JNI::_MID_getScummVMConfigPath;
jmethodID JNI::_MID_getScummVMLogPath;
jmethodID JNI::_MID_setCurrentGame = 0;
jmethodID JNI::_MID_getSysArchives = 0;
jmethodID JNI::_MID_getAllStorageLocations = 0;
jmethodID JNI::_MID_initSurface = 0;
@ -614,6 +615,27 @@ Common::String JNI::getScummVMLogPath() {
return path;
}
void JNI::setCurrentGame(const Common::String &target) {
JNIEnv *env = JNI::getEnv();
jstring java_target = nullptr;
if (!target.empty()) {
java_target = convertToJString(env, Common::U32String(target));
}
env->CallVoidMethod(_jobj, _MID_setCurrentGame, java_target);
if (env->ExceptionCheck()) {
LOGE("Failed to set current game");
env->ExceptionDescribe();
env->ExceptionClear();
}
if (java_target) {
env->DeleteLocalRef(java_target);
}
}
// 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 base directory, with a higher priority
@ -804,6 +826,7 @@ void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
FIND_METHOD(, getScummVMBasePath, "()Ljava/lang/String;");
FIND_METHOD(, getScummVMConfigPath, "()Ljava/lang/String;");
FIND_METHOD(, getScummVMLogPath, "()Ljava/lang/String;");
FIND_METHOD(, setCurrentGame, "(Ljava/lang/String;)V");
FIND_METHOD(, getSysArchives, "()[Ljava/lang/String;");
FIND_METHOD(, getAllStorageLocations, "()[Ljava/lang/String;");
FIND_METHOD(, initSurface, "()Ljavax/microedition/khronos/egl/EGLSurface;");

View File

@ -101,6 +101,7 @@ public:
static Common::String getScummVMConfigPath();
static Common::String getScummVMLogPath();
static jint getAndroidSDKVersionId();
static void setCurrentGame(const Common::String &target);
static inline bool haveSurface();
static inline bool swapBuffers();
@ -161,6 +162,7 @@ private:
static jmethodID _MID_getScummVMBasePath;
static jmethodID _MID_getScummVMConfigPath;
static jmethodID _MID_getScummVMLogPath;
static jmethodID _MID_setCurrentGame;
static jmethodID _MID_getSysArchives;
static jmethodID _MID_getAllStorageLocations;
static jmethodID _MID_initSurface;

View File

@ -86,6 +86,7 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
abstract protected String getScummVMBasePath();
abstract protected String getScummVMConfigPath();
abstract protected String getScummVMLogPath();
abstract protected void setCurrentGame(String target);
abstract protected String[] getSysArchives();
abstract protected String[] getAllStorageLocations();
abstract protected String[] getAllStorageLocationsNoPermissionRequest();

View File

@ -61,7 +61,6 @@ import java.util.Map;
import java.util.TreeSet;
public class ScummVMActivity extends Activity implements OnKeyboardVisibilityListener {
/* Establish whether the hover events are available */
private static boolean _hoverAvailable;
@ -839,6 +838,18 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
} else return "";
}
@Override
protected void setCurrentGame(String target) {
Uri data = null;
if (target != null) {
data = Uri.fromParts("scummvm", target, null);
}
Intent intent = new Intent(Intent.ACTION_MAIN, data,
ScummVMActivity.this, ScummVMActivity.class);
setIntent(intent);
Log.d(ScummVM.LOG_TAG, "Current activity Intent is: " + data);
}
@Override
protected String[] getSysArchives() {
Log.d(ScummVM.LOG_TAG, "Adding to Search Archive: " + _actualScummVMDataDir.getPath());
@ -908,7 +919,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
@Override
public void onCreate(Bundle savedInstanceState) {
// Log.d(ScummVM.LOG_TAG, "onCreate");
// Log.d(ScummVM.LOG_TAG, "onCreate: " + getIntent().getData());
super.onCreate(savedInstanceState);
@ -1009,9 +1020,19 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
// We should have a valid path to a configuration file here
// Start ScummVM
_scummvm.setArgs(new String[]{
"ScummVM"
});
final Uri intentData = getIntent().getData();
String[] args;
if (intentData == null) {
args = new String[]{
"ScummVM"
};
} else {
args = new String[]{
"ScummVM",
intentData.getSchemeSpecificPart()
};
}
_scummvm.setArgs(args);
Log.d(ScummVM.LOG_TAG, "Hover available: " + _hoverAvailable);
_mouseHelper = null;
@ -1054,6 +1075,64 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
super.onStart();
}
@Override
protected void onNewIntent(Intent intent) {
// Log.d(ScummVM.LOG_TAG, "onNewIntent: " + intent.getData());
super.onNewIntent(intent);
Uri intentData = intent.getData();
// No specific game, we just continue
if (intentData == null) {
return;
}
// Same game requested, we continue too
if (intentData.equals(getIntent().getData())) {
return;
}
setIntent(intent);
if (_events == null) {
finish();
startActivity(intent);
return;
}
// Don't finish our activity on C++ end
_finishing = true;
_events.clearEventHandler();
_events.sendQuitEvent();
// Make sure the thread is actively polling for events
_scummvm.setPause(false);
try {
// 1s timeout
_scummvm_thread.join(2000);
} catch (InterruptedException e) {
Log.i(ScummVM.LOG_TAG, "Error while joining ScummVM thread", e);
}
// Our join failed: kill ourselves to not have two ScummVM running at the same time
if (_scummvm_thread.isAlive()) {
Process.killProcess(Process.myPid());
}
_finishing = false;
String[] args = new String[]{
"ScummVM",
intentData.getSchemeSpecificPart()
};
_scummvm.setArgs(args);
_scummvm_thread = new Thread(_scummvm, "ScummVM");
_scummvm_thread.start();
}
@Override
public void onResume() {
// Log.d(ScummVM.LOG_TAG, "onResume");

View File

@ -40,7 +40,9 @@ public class SplashActivity extends Activity {
// and they are automatically denied -- onRequestPermissionsResult() will be called without user's input
requestPermissions(MY_PERMISSIONS_STR_LIST, MY_PERMISSION_ALL);
} else {
startActivity(new Intent(this, ScummVMActivity.class));
Intent next = new Intent(this, ScummVMActivity.class);
next.fillIn(getIntent(), Intent.FILL_IN_ACTION | Intent.FILL_IN_DATA);
startActivity(next);
finish();
}
}