diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp index d8084b11585..8aee751d060 100644 --- a/backends/platform/android/android.cpp +++ b/backends/platform/android/android.cpp @@ -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() { diff --git a/backends/platform/android/jni-android.cpp b/backends/platform/android/jni-android.cpp index 80c796f48a5..a8f42e98906 100644 --- a/backends/platform/android/jni-android.cpp +++ b/backends/platform/android/jni-android.cpp @@ -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;"); diff --git a/backends/platform/android/jni-android.h b/backends/platform/android/jni-android.h index 6b887e9bc29..29dae5ebf22 100644 --- a/backends/platform/android/jni-android.h +++ b/backends/platform/android/jni-android.h @@ -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; diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVM.java b/backends/platform/android/org/scummvm/scummvm/ScummVM.java index d9208e298c3..c47db1f380c 100644 --- a/backends/platform/android/org/scummvm/scummvm/ScummVM.java +++ b/backends/platform/android/org/scummvm/scummvm/ScummVM.java @@ -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(); diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java index 483b0dd850b..30c90b32d0a 100644 --- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java +++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java @@ -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"); diff --git a/backends/platform/android/org/scummvm/scummvm/SplashActivity.java b/backends/platform/android/org/scummvm/scummvm/SplashActivity.java index 91d53fd4ecb..abe6a526e80 100644 --- a/backends/platform/android/org/scummvm/scummvm/SplashActivity.java +++ b/backends/platform/android/org/scummvm/scummvm/SplashActivity.java @@ -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(); } }