diff --git a/android/android_studio_project/app/src/main/java/jp/xenia/XeniaRuntimeException.java b/android/android_studio_project/app/src/main/java/jp/xenia/XeniaRuntimeException.java new file mode 100644 index 000000000..93a046dfb --- /dev/null +++ b/android/android_studio_project/app/src/main/java/jp/xenia/XeniaRuntimeException.java @@ -0,0 +1,21 @@ +package jp.xenia; + +/** + * Base class for all unchecked exceptions thrown by the Xenia project components. + */ +public class XeniaRuntimeException extends RuntimeException { + public XeniaRuntimeException() { + } + + public XeniaRuntimeException(String name) { + super(name); + } + + public XeniaRuntimeException(String name, Throwable cause) { + super(name, cause); + } + + public XeniaRuntimeException(Exception cause) { + super(cause); + } +} diff --git a/android/android_studio_project/app/src/main/java/jp/xenia/emulator/WindowedAppActivity.java b/android/android_studio_project/app/src/main/java/jp/xenia/emulator/WindowedAppActivity.java index dd89881c3..9deb60358 100644 --- a/android/android_studio_project/app/src/main/java/jp/xenia/emulator/WindowedAppActivity.java +++ b/android/android_studio_project/app/src/main/java/jp/xenia/emulator/WindowedAppActivity.java @@ -3,11 +3,10 @@ package jp.xenia.emulator; import android.app.Activity; import android.content.res.AssetManager; import android.os.Bundle; -import android.util.Log; + +import jp.xenia.XeniaRuntimeException; public abstract class WindowedAppActivity extends Activity { - private static final String TAG = "WindowedAppActivity"; - static { // TODO(Triang3l): Move all demos to libxenia.so. System.loadLibrary("xenia-ui-window-vulkan-demo"); @@ -26,11 +25,12 @@ public abstract class WindowedAppActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mAppContext = initializeWindowedAppOnCreateNative(getWindowedAppIdentifier(), getAssets()); + final String windowedAppIdentifier = getWindowedAppIdentifier(); + mAppContext = initializeWindowedAppOnCreateNative(windowedAppIdentifier, getAssets()); if (mAppContext == 0) { - Log.e(TAG, "Error initializing the windowed app"); finish(); - return; + throw new XeniaRuntimeException( + "Error initializing the windowed app " + windowedAppIdentifier); } } diff --git a/src/xenia/base/logging.cc b/src/xenia/base/logging.cc index d5b9ccef7..bed2fe43b 100644 --- a/src/xenia/base/logging.cc +++ b/src/xenia/base/logging.cc @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -500,7 +501,13 @@ void FatalError(const std::string_view str) { } ShutdownLogging(); - std::exit(1); + +#if XE_PLATFORM_ANDROID + // Throw an error that can be reported to the developers via the store. + std::abort(); +#else + std::exit(EXIT_FAILURE); +#endif // XE_PLATFORM_ANDROID } } // namespace xe diff --git a/src/xenia/base/system_android.cc b/src/xenia/base/system_android.cc new file mode 100644 index 000000000..8290172ca --- /dev/null +++ b/src/xenia/base/system_android.cc @@ -0,0 +1,36 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2022 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include "xenia/base/assert.h" +#include "xenia/base/system.h" + +namespace xe { + +void LaunchWebBrowser(const std::string_view url) { + // TODO(Triang3l): Intent.ACTION_VIEW (need a Java VM for the thread - + // possibly restrict this to the UI thread). + assert_always(); +} + +void LaunchFileExplorer(const std::filesystem::path& path) { assert_always(); } + +void ShowSimpleMessageBox(SimpleMessageBoxType type, std::string_view message) { + // TODO(Triang3l): Likely not needed much at all. ShowSimpleMessageBox is a + // concept pretty unfriendly to platforms like Android because it's blocking, + // and because it can be called from threads other than the UI thread. In the + // normal execution flow, dialogs should preferably be asynchronous, and used + // only in the UI thread. However, non-blocking messages may be good for error + // reporting - investigate the usage of Toasts with respect to threads, and + // aborting the process immediately after showing a Toast. For a Toast, the + // Java VM for the calling thread is needed. +} + +} // namespace xe diff --git a/src/xenia/base/system_linux.cc b/src/xenia/base/system_gnulinux.cc similarity index 100% rename from src/xenia/base/system_linux.cc rename to src/xenia/base/system_gnulinux.cc